彩票走势图

用MVVM方式让DataPager分页控件实现服务器端分页

转帖|其它|编辑:郝浩|2011-05-31 14:26:27.000|阅读 1284 次

概述:在上一篇文章中,我们实现了如何让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也没有必要设,因为我们是在服务器端计算分页数的!)


标签:MVVM

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn

文章转载自:博客园

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP