让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分页控件实现服务器端分页_第1张图片

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

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是“服务端分页”了。每次只返回一页数据。

让DataPager分页控件实现服务器端分页_第2张图片

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

Domain DataSource控件

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

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

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

你可能感兴趣的:(PAGER)