Silverlight DataGrid 本身是不带分页功能同时他排序也是针对当前页面内容进行排序而这两样功能在实际项目中都是必须带上网搜索了下好像目前还没有那篇文章介绍过如何实现这两个常用功能看样子只要自己动手了呵呵
下面我们来步步实现这些功能(以下都以NorthWind数据库为演示) 第步我们先实现分页
要分页首先要在WCF上加上个分页获取数据思路方法先上代码
1 [OperationContract]
2 publicList<Products>GetProductsPaging(start,limit,sort,dir,outTotalPage)
3 {
4 NorthWindLinqDataContextdb=NorthWindLinqDataContext;
5 sql;
6 sql="selectcount(*)ascfromProducts";
7 TotalCount=db.ExecuteQuery<>(sql).Single;
8 TotalPage=Convert.ToInt32(Math.Ceiling((double)TotalCount/(double)limit));
9 sql="withaas(SELECT*,row_numberover(orderby{0})asrownumberFROMProducts)select*fromawhererownumberbetween{1}and{2}";
10 sql=.Format(sql,sort+""+dir,start,start+limit-1);
11 varquery=db.ExecuteQuery<Products>(sql);
12 query.ToList;
13 }
14
代码比较简单用了sql2005分页思路方法就不做解释了至于这分页思路方法效率如何样不是本次学习重点先不管了
数据库访问使用LinqToSQL做本来想用Linq实现分页功能但是忙活了半天最终以失败告终主要问题是我没办法在Linq中实现动态排序网上也没有找到个合适思路方法只能写n个进行排序就像下面代码:
1 var products =frompindb.Products
2 select p;
3 (dir"ProductName")
4 products=products.OrderBy(p=>p.ProductName);
5 (dir"ProductID")
6 products=products.OrderBy(p=>p.ProductID);
7 .......
这样写话虽然功能能实现但是实在是有点弱智要写上大堆代码真不如写sql呢最终还是没有搞定这个问题只好写sql语句了如果大家有什么好办法能实现话请留言告诉我谢谢了!
ok到此分页基本功能搞定了DataGrid已经可以获取分页数据了但是这个DataGrid和Web上不样没有Pager晕只要手工写个PagerControl控件了
第 2步实现Pager
动手的前老办法先上网找现成呵呵不错这次终于有点结果了网上不少这样例子在silverlight.net上找了个Pager先用着再说呵呵
这个是地址http://www.13sides.com/page/A-Generic-Pager-Control.aspx大家自己去看吧使用方法很简单
现在把代码整合起来ok已经可以正确分页了哈哈接下来我们来实现排序
第 3步实现排序
要排序当然是要点击ColumnHeader了在DataGrid中找ColumnHeader点击事件晕没有不会吧这个微软如何搞啊虽然Silverlight都2.0了但是如何看都还是像个半成品啊这样常用事件都没有半成品就半成品吧继续手工实现吧
又是老办法上网找现成呵呵两种方案种是把Header改成模板然后里面放上Button这样就可以实现了还有种有人提到了用DataGridHitTest思路方法呵呵第个有点费事每个Header都要改第 2个看起来酷点所以我选择了第 2种
试验了下晕HitTest如何成了不可访问受保护级别限制再查MSDN呵呵原来2.0里面该成了VisualTreeHelper.FindElementsInHostCoordinates了ok下面上代码:
在DataGridMouseLeftButtonDown写这里有个奇怪问题点击ColumnHeader并不会触发MouseLeftButtonUp事件真搞不明白
1 privatevoiddgData_MouseLeftButtonDown(objectsender,MouseButtonEventArgse)
2 {
3 //获取点击ColumnHeader
4 varu=fromelementinVisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(null),dgData)
5 whereelementisDataGridColumnHeader
6 selectelement;
7
8 (u.Count1)
9 {
10 DataGridColumnHeaderheader=(DataGridColumnHeader)u.Single;
11 //为什么要把这个header保存下来下面会介绍原因
12 sortHeader=header;
13 //获取到字段名称
14 headername=header.Content.;
15 //跟现在排序字段比较下确定应该是desc还是asc
16 sort=header.Content.;
17 (sortsort)
18 dir=dir"desc"?"asc":"desc";
19
20 dir="asc";
21 sort=sort;
22 //绑定数据
23 BindGrid;
24 e.Handled=true;
25 }
26
27 e.Handled=false;
28 }
好到此整个分页、排序功能就基本上完成了
呵呵仔细用下发现我们在实现了排序的后DataGrid 然而会自作聪明帮我们数据又排了下并且DataGrid默认是支持列拖动当我们拖动列时会触发排序导致结果和用户预计不样那如何解决呢
直接在DataGrid中设置 CanUserSortColumns="False"和CanUserReorderColumns="False"就可以解决了
再在测试下发现在排序的后ColumnHeader上面并没有显示标示排序方向小箭头查了下MSDN上面在介绍 DataGrid 样式和模板时候提到过DataGridColumnHeader 状态里面有SortAscending和SortDescending这两种状态ok我们就接着写了个思路方法来设置Header状态在上面MouseLeftButtonDown中我们曾经把排序Header保存了下来就是为了在这里使用代码如下:
1 privatevoidColumnSortState
2 {
3 (dir"asc")
4 VisualStateManager.GoToState(sortHeader, "SortAscending",false);
5
6 VisualStateManager.GoToState(sortHeader, "SortDescending",false);
7 }
很简单但是有个奇怪问题就是在排序的后设置了Header状态并不能保存下来鼠标移动那个小箭头就会消失具体原因我也不明白我不太清楚VisualStateManager.GoToState在设置了Header状态是不是和DataGrid自带排序功能有关联才导致了排序小箭头会自动消失或者在这里根本就不应该用这个思路方法暂时我没有去考虑这个问题为了让排序小箭头能正确显示我只好在GridMouseMove和LayoutUpdated事件里都了ColumnSortState用来保证小箭头可以正确显示
至此整个分页、排序功能全部完成除了那个小箭头显示处理不完美的外其它到也没有什么大问题我会在后面学习中来解决这个问题
最新评论