让DataPager分页控件实现服务器端分页

Silverlight4中有一个DataPager分页控件,使用起来非常简单,拖过来,这样设置一下就可以用了,就可以搭配List(比如DataGrid)使用了,真是简单:

最简单的客户端分页

1 PagedCollectionView pcv = new PagedCollectionView(MyEntities/*IEnumerable<T>*/);
2
3  this.dataPager1.PageSize = 10;
4
5  this.dataGrid1.ItemsSource = pcv;
6  this.dataPager1.Source = pcv;

然后就可以实现分页了,效果如图:

DataPager+DataGrid

好简单,那我们今天还写什么,文章可以结束了。呵呵。

Fiddler分析了一下客户端和服务端的数据,发现这个DataPager是“客户端分页”。也就是说,如果你数据库有百万数据,都下载到客户端来了,然后在Silverlight客户端做了一把分页,显示当前页数据。这个这个,如果你的数据量不大,这个没有问题,如果数据量大,那就有性能问题了。解决办法只能是服务器端分页。不难。我们不用几分钟就能搞定。

服务端分页函数(WCF/WCF Ria Service)

首先,服务器端写两个函数,一个是计算总的页数,另一个是取得当前页的数据。举例来说,我服务器端用的是WCF Ria Service(只是例子,没有具体意义的):

1 //取得当前页的数据
2  public IQueryable<MyEntity> GetMyEntities(int PageSize, int CurrentPage)
3 {
4 if (CurrentPage <= 1)
5 return this.ObjectContext.MyEntity.Where(s => s.EntityID > 1).OrderByDescending(e => e.EntityChangedAt).Take(PageSize);
6 else
7 return this.ObjectContext.MyEntity.Where(s => s.EntityID > 1).OrderByDescending(e => e.EntityChangedAt).Skip(PageSize * (CurrentPage - 1)).Take(PageSize);
8 }
9
10  //计算总页数
11  [Invoke]
12 public int GetEntityTotalPages(int PageSize)
13 {
14 return Int32.Parse(Math.Ceiling(Convert.ToDouble(this.ObjectContext.MyEntity.Where(s => s.EntityID > 1).Count()) / Convert.ToDouble(PageSize)).ToString());
15 }

Silverlight调用/in *.Xaml.cs(下一篇讲MVVM的方式)

接下来,就是在*.xaml.cs中获取服务器端数据了,代码都带注释了,应该很好懂:

1 public partial class MainPage : UserControl
2 {
3 private const int PageSize = 10;
4 private List<int> itemCount = new List<int>();
5 private MyDomainContext d = new MyDomainContext();//Ria Service Context
6
7 public MainPage()
8 {
9 InitializeComponent();
10
11 //点击页码的事件,获取当前页的数据并绑定到DataGrid
12 this.dataPager1.PageIndexChanged += (s, e) =>
13 {
14 this.Cursor = Cursors.Wait;
15
16 d.Load<MyEntity>(d.GetMyEntitiesQuery(PageSize, ((DataPager)s).PageIndex + 1), lo =>
17 {
18 if (!lo.HasError)
19 {
20 PagedCollectionView pcv = new PagedCollectionView(lo.Entities);
21 this.dataGrid1.ItemsSource = pcv;
22 this.Cursor = Cursors.Arrow;
23 }
24 }, null);
25 };
26 }
27
28 //按钮点击加载数据
29 private void button1_Click(object sender, RoutedEventArgs e)
30 {
31 this.Cursor = Cursors.Wait;
32
33 //获得总的页码数,绑定到DataPager
34 d.GetEntityTotalPages(PageSize, s =>
35 {
36 if (!s.HasError)
37 {
38 int totalpagers = s.Value;
39
40 for (int i = 1; i <= totalpagers; i++)
41 itemCount.Add(i);
42
43 PagedCollectionView pcv = new PagedCollectionView(itemCount);
44 pcv.PageSize = 1;
45 this.dataPager1.Source = pcv; //这儿会自动触发this.dataPager1.PageIndexChanged事件
46 }
47 }, null);
48
49 }
50
51 }

前台Xaml代码就是拖一个DataGrid,拖一个DataPager,灰常简单,不写了。

Fiddler查看下载的真正数据

再次用Fiddler分析了一下客户端和服务端的数据,发现这个DataPager是“服务端分页”了。每次只返回一页数据。

Fiddler

不用源码了吧,都贴在文章里了。(下一篇我们把上面的前台代码用MVVM模式整理一下,清爽一点!)

Domain DataSource控件

如果你用的是Toolkit的DomainDataSource控件来处理paging, sorting, filtering ... 那就忽略本文,因为它每次是take=100,只取本页数据的,但这个控件不是MVVM模式,注意一下)

更强悍的服务器端分页/排序/过滤/搜索 - MVVM友好

看这一篇文章《EntityList<T>/DomainCollectionView<T>/DomainCollectionViewLoader<T>》 

Powered By D&J (URL:http://www.cnblogs.com/Areas/)
原文地址:https://www.cnblogs.com/Areas/p/2169535.html