轉帖|其它|編輯:郝浩|2011-05-31 14:26:27.000|閱讀 1330 次
概述:在上一篇文章中,我們實現了如何讓Silverlight4中的DataPager控件實現服務器端分頁而不是客戶端分頁,我們在服務器端的WCF Ria Service實現了一個取得總頁數的函數和一個按頁碼取得數據的函數。今天補充一下,把上文的前臺部分用MVVM的模式實現。也比較簡單的。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
在上一篇文章中,我們實現了如何讓Silverlight4中的DataPager控件實現服務器端分頁而不是客戶端分頁,我們在服務器端的WCF Ria Service實現了一個取得總頁數的函數和一個按頁碼取得數據的函數。今天補充一下,把上文的前臺部分用MVVM的模式實現。也比較簡單的。
先看一下Xaml代碼,我們實現一個DataGrid和一個DataPager,有一個BusyIndicator,當DataGrid加載數據的時候自動顯示一個進度條并灰掉后面的控件,這個是和ViewModel的IsBusy綁定的,具體實現看我的另外一篇文章。代碼:
<UserControl x:Class="MySilverlightApplication"
xmlns="//schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="//schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="//schemas.microsoft.com/expression/blend/2008"
xmlns:i="//schemas.microsoft.com/expression/2010/interactivity"
xmlns:mc="//schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:Height="Auto" d:Width="Auto" xmlns:sdk=
"//schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:toolkit=
"//schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit">
<Grid x:Name="LayoutRoot" Background="White">
<toolkit:HeaderedContentControl Name=
"headeredContentControl1" Width="Auto">
<toolkit:BusyIndicator Name="busyIndicator1" IsBusy=
"{Binding IsBusy}" DisplayAfter="0" BusyContent="Fetching data...">
<sdk:DataGrid AutoGenerateColumns="False"
GridLinesVisibility="None" Width="Auto"
HorizontalAlignment="Stretch" VerticalAlignment=
"Stretch" BorderThickness="0,0,0,0" SelectionMode="Single"
Name="dgvRecentUpdated" IsReadOnly="True">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Header="ProductID" Binding=
"{Binding ProductID}" Visibility="Collapsed" />
<sdk:DataGridTextColumn Header="Product Name"
Binding="{Binding Name}" Width="120" />
<sdk:DataGridTextColumn Header="Product Desc"
Binding="{Binding Desc}" Width="120"/>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</toolkit:BusyIndicator>
</toolkit:HeaderedContentControl>
<sdk:DataPager Height="25" HorizontalAlignment=
"Stretch" Name="dataPager1" Source="{Binding PagerContext}"
VerticalAlignment="Bottom" Width="Auto" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="PageIndexChanged">
<i:InvokeCommandAction Command=
"{Binding SetResultsByPagerCommand}" CommandParameter="
{Binding PageIndex, ElementName=dataPager1, Mode=OneWay}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</sdk:DataPager>
</Grid>
</UserControl>
注意DataPager的Source綁定,PageIndexChanged事件綁定到Command,綁定的事件的參數是PageIndex - 請求的頁碼。
先來實現PageIndexChanged事件綁定的SetResultsByPagerCommand :
//在ViewModel構造函數中
SetResultsByPagerCommand = new DelegateCommand
(SetResultsByPager, CanSetResultsByPager);
//....
private int _PageSize = 10;
public ICommand SetResultsByPagerCommand { get; set; }
public void SetResultsByPager(object param)
{
//調用WCF Ria Service得到當前頁碼的數據
PerformQuery<MyEntity>(
MyDomainContext.GetDataQuery("234", _PageSize,
Convert.ToInt32(param) + 1), //這個是當前的頁碼
GetMyDataComplete); //在這個事件中更新DataGrid模型,自動通知界面
}
private bool CanSetResultsByPager(object param)
{
return true;
}
再來實現DataPager綁定的Source - PagerContext:
private List<int> pagerItemsCount;
private PagedCollectionView _PagerContext;
public PagedCollectionView PagerContext
{
get
{
if (pagerItemsCount == null)
pagerItemsCount = new List<int>();
if (_PagerContext == null)
{
PagedCollectionView pcv = new PagedCollectionView(pagerItemsCount);
pcv.PageSize = 1;
_PagerContext = pcv;
}
return _PagerContext;
}
set
{
if (PagerContext == value)
return;
_PagerContext = value;
NotifyPropertyChanged("PagerContext"); //會自動通知刷新DataPager
}
}
最后就是初始化DataPager,或者在你需要數據的地方去從服務器端獲得總頁數并load這個DataPager的Source了,比如這樣:
MyDomainContext.GetTotalPages("123",
_PageSize, s =>
{
if (!s.HasError)
{
if (pagerItemsCount != null)
pagerItemsCount.Clear();
for (int i = 1; i <= s.Value; i++)
pagerItemsCount.Add(i);
PagedCollectionView pcv = new PagedCollectionView(pagerItemsCount);
pcv.PageSize = 1;
PagerContext = pcv; //刷新DataPager綁定的Source
SetResultsByPager(0); //強制跳轉到第一頁,這一步也可以省略,如果你是初始化就加載這個視圖的話。
}
else
{
// 通知發生了錯誤
//if (LoadingCompleteFailed != null)
// LoadingCompleteFailed(this, new ResultsArgs(s.Error));
}
}, null);
整個邏輯就是:從服務器獲得總頁數 >> 異步完成的時候綁定到DataPager的Source >> 自動觸發IndexChanged >> 從服務器端加載指定頁的數據并顯示 >> 用戶可以任意導航上一頁下一頁....
這樣我們在*.Xaml.cs里面沒有任何代碼,非常清爽的MVVM模式實現!
(注意:有人還畫蛇添足綁定了DataPager的PageSize屬性和CurrentIndex屬性到ViewModel,根本沒有必要,這些DataPager的PageIndex會自動管理當前的頁碼數。PageSize也沒有必要設,因為我們是在服務器端計算分頁數的!)
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:博客園