使用Silverlight3中的DataPager实现服务器端分页
代振軍同學的blog中描述了使用DataPager實現客戶端分頁:
http://www.cnblogs.com/daizhj/archive/2009/08/07/1529331.html
一般說來,在項目中一般很少使用這種客戶端的分頁方式,除非數據量很少(干脆不分頁算了)。
把大量的數據一次性傳輸到客戶端可不是個明智的做法,我們一般都是從客戶端傳入查找條件參數(包括過濾條件和分頁條件參數),然后服務端從數據庫中找出符合查找條件的的記錄列表傳輸給客戶端,客戶端綁定到DataGrid控件上。
這里使用“開啟了Silverlight的WCF服務”來和客戶端(silverlight)程序進行通信,數據訪問采用Ado.net Entity Framework,解決方案結構如圖:
建立了一個測試用的數據庫:包含兩張表:
該實例除了演示了使用DataPager的服務器端分頁外還實現了使用Entity SQL的動態查找功能:
分頁控件很多人都寫過,但不像DataPager那樣要傳入個PagedCollectionView才行,一般傳入總記錄數和分頁大小就可以了,所以,我們給Datapager增加一個擴展方法來綁定總記錄數和分頁大小:
public?static?class?DataPageExtension
????{
????????public?static?void?BindSource(this?DataPager?dataPager,?int?totalCount,?int?pageSize)
????????{
????????????List<int>?list?=?new?List<int>(totalCount);
????????????for?(int?i?=?0;?i?<?totalCount;?i++)?list.Add(i);
????????????PagedCollectionView?pcv?=?new?PagedCollectionView(list);
????????????pcv.PageSize?=?pageSize;
????????????dataPager.Source?=?pcv;
????????}
????}
WCF服務端的分頁方法如下:
Code?[OperationContract]
????????public?List<MyEmployee>?GetEmployeeList(EmployeeFilter?filter,out?int?totalCount)
????????{
????????????using?(TestDBEntities?db?=?new?TestDBEntities())
????????????{
????????????????int?rowsCount?=?0;
????????????????StringBuilder?sbSql?=?new?StringBuilder("True?");
????????????????if?(filter.DeptID?!=?new?Guid())
????????????????????sbSql.Append(string.Format("and?it.Departments.DepartmentID?=?Guid'{0}'",?filter.DeptID));
????????????????sbSql.Append(string.Format("and?it.EmpolyeeName?like?'%{0}%'",?filter.EmpName));
????????????????var?query?=?from?emp?in?db.Employees.Where(sbSql.ToString())
????????????????????????????select?new?MyEmployee
????????????????????????????{
????????????????????????????????ID?=?emp.EmployeeID,
????????????????????????????????Name?=?emp.EmpolyeeName,
????????????????????????????????Sex?=?emp.EmployeeSex???"男"?:?"女",
????????????????????????????????Age?=?emp.EmployeeAge,
????????????????????????????????Address?=?emp.EmployeeAddress,
????????????????????????????????DeptName?=?emp.Departments.DepartmentName
????????????????????????????};
????????????????if?(filter.PageIndex?<=?0)
????????????????????rowsCount?=?query.Count();
????????????????totalCount?=?rowsCount;
????????????????query?=?query.OrderBy(t?=>?t.Name).Skip(filter.PageIndex?*?filter.PageSize).Take(filter.PageSize);
????????????????return?query.ToList();
????????????}
????????}
上面的代碼實現了使用Entity SQl的動態查找功能和分頁功能,可以看到:只有當pageindex 等于0的時候才計算總記錄數,提高了方法執行的效率;方法的輸入參數和輸出參數都進行了實體類的封裝,建議在實際項目中也這樣做,特別是在使用依賴注入的時候。
在客戶端(Silverlight項目)中引用好服務后,頁面的cs代碼如下:
using?System;
using?System.Collections.Generic;
using?System.Linq;
using?System.Net;
using?System.Windows;
using?System.Windows.Controls;
using?System.Windows.Documents;
using?System.Windows.Input;
using?System.Windows.Media;
using?System.Windows.Media.Animation;
using?System.Windows.Shapes;
using?System.Windows.Data;
using?DataPagerTest.EmployeeServiceReference;
namespace?DataPagerTest
{
????public?partial?class?MainPage?:?UserControl
????{
????????EmployeeServiceClient?client?=?new?EmployeeServiceClient();
????????EmployeeFilter?filter?=?new?EmployeeFilter();
????????public?MainPage()
????????{
????????????InitializeComponent();
????????}
????????private?void?UserControl_Loaded(object?sender,?RoutedEventArgs?e)
????????{
????????????dpEmployee.PageIndexChanged?+=?new?EventHandler<EventArgs>(dpEmployee_PageIndexChanged);
????????????cbDept.SelectionChanged?+=?new?SelectionChangedEventHandler(cbDept_SelectionChanged);
????????????BindCombox();
????????}
????????void?cbDept_SelectionChanged(object?sender,?SelectionChangedEventArgs?e)
????????{
????????????BindGrid(0);
????????}
????????void?dpEmployee_PageIndexChanged(object?sender,?EventArgs?e)
????????{
????????????BindGrid(dpEmployee.PageIndex);
????????}
????????private?void?btnQuery_Click(object?sender,?RoutedEventArgs?e)
????????{
????????????BindGrid(0);
????????}
????????private?void?BindGrid(int?pageIndex)
????????{
????????????Departments?dept?=?cbDept.SelectedItem?as?Departments;
????????????filter.DeptID?=?dept.DepartmentID;
????????????filter.EmpName?=?tbEmpName.Text.Trim();
????????????filter.PageIndex?=?pageIndex;
????????????filter.PageSize?=?9;
????????????client.GetEmployeeListCompleted?+=?new?EventHandler<GetEmployeeListCompletedEventArgs>(client_GetEmployeeListCompleted);
????????????client.GetEmployeeListAsync(filter);
????????}
????????void?client_GetEmployeeListCompleted(object?sender,?GetEmployeeListCompletedEventArgs?e)
????????{
????????????dgEmployee.ItemsSource?=?e.Result;
????????????if?(filter.PageIndex?<=?0)
????????????????dpEmployee.BindSource(e.totalCount,?filter.PageSize);
????????}
????????void?BindCombox()
????????{
????????????client.GetDepartmentListCompleted?+=?new?EventHandler<GetDepartmentListCompletedEventArgs>(client_GetDepartmentListCompleted);
????????????client.GetDepartmentListAsync();
????????}
????????void?client_GetDepartmentListCompleted(object?sender,?GetDepartmentListCompletedEventArgs?e)
????????{
????????????cbDept.ItemsSource?=?e.Result;
????????????cbDept.DisplayMemberPath?=?"DepartmentName";
????????????cbDept.SelectedIndex?=?0;
????????????BindGrid(0);
????????}
????????
????????
????}
}
在PageIndex等于0的時候調用BindSource擴展方法來綁定總記錄數和頁大小;里面還有個關于Combobox的數據綁定方法。這樣的分頁方法不知大家有何評價,歡迎拍磚。
?2009-08-18 更新:修改了數據庫的Departments表結構,實現了在Combobox里顯示TreeView的效果(如效果圖)。
總結
以上是生活随笔為你收集整理的使用Silverlight3中的DataPager实现服务器端分页的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 你的网站添加X-UA-Compatibl
- 下一篇: 图解入侵过程,黑客未来!