Cyl*_*Cat 13 silverlight-3.0 datapager wcf-ria-services
我仍然试图通过Silverlight和RIA Services来实现我的目标,当然还要从一些更"有趣"的东西开始,比如网格和智能分页.我可以连接到RIA Services(使用自行开发的ORM,而不是L2S或EF),在网格上获取数据,并连接到DataPager.域服务与本土ORM一起运行良好,至少对于查询而言.(仍在使用完整的CRUD.)但是,仍然存在问题:
为了支持用户应用程序,除了智能分页(仅运行查询显示所需的行)和分组之外,我还需要用户控制的排序和过滤.
到目前为止,我在DataGrid或DataPager中没有看到任何外部化这些功能的内容,因此可以将过滤,排序和分页参数传递给服务器以构建适当的查询.
数据集可能非常大; 我选择用于原型制作工作的我的表可以在一些客户中拥有多达35,000个条目,我确信还有其他更大的表格,我将不得不在某个时候处理.因此,"智能寻呼"方面至关重要.
我们欢迎您的想法,建议,指导和nerf砖.
Cyl*_*Cat 11
好吧,我已经花了几天杂草用这个,我想我已经掌握了它.
首先,一件重要的魔力.要使分页正常工作,无论当前查询返回多少项,寻呼机都必须知道总项数.如果查询返回所有内容,则项目计数显然是返回的项目数.对于智能分页,项目计数仍然是可用项目的总数,尽管查询仅返回显示的内容.通过过滤,每次过滤器更改时,甚至可用项的总数也会发生变化.
Silverlight Datapager控件具有名为ItemCount的属性.它是只读的,不能在XAML中数据绑定,或直接在代码中设置.但是,如果包含寻呼机的用户控件具有实现IPagedCollectionView的DataContext,则数据上下文对象必须使用PropertyChanged通知实现ItemCount属性,并且DataPager似乎自动选择它.
其次,我强烈推荐Brad Abrams 关于RIA服务的优秀系列博客文章,尤其是ViewModel 上的这篇博文.它包含了进行分页和过滤工作所需的大部分内容,尽管它缺少管理项目计数的关键部分.他的可下载示例还包含一个非常好的实现ModelViewViewModel(MVVM)的基本框架.谢谢你,布拉德!
所以这里是如何使项目计数工作.(此代码引用自定义ORM,而Brad的代码使用实体框架;在两者之间,您可以找到您在环境中需要的内容.)
首先,您的ORM需要支持获取记录计数,无论您是否使用过滤器.这是我的域名服务代码,可以为RIA服务提供计数:
[Invoke]
public int GetExamCount()
{
return Context.Exams.Count();
}
[Invoke]
public int GetFilteredExamCount(string descriptionFilter)
{
return Context.Exams.GetFilteredCount(descriptionFilter);
}
Run Code Online (Sandbox Code Playgroud)
注意[Invoke]属性.对于不返回Entity或Entity集合的任何DomainService方法,您需要这样做.
现在为ViewModel代码.当然,你需要一个ItemCount.(这是布拉德的例子.)
int itemCount;
public int ItemCount
{
get { return itemCount; }
set
{
if (itemCount != value)
{
itemCount = value;
RaisePropertyChanged(ItemCountChangedEventArgs);
}
}
}
Run Code Online (Sandbox Code Playgroud)
您的LoadData方法将运行查询以获取要在DataGrid中显示的当前行集.(这还没有实现自定义排序,但这是一个简单的添加.)
EntityQuery<ExamEntity> query =
DomainContext.GetPagedExamsQuery(PageSize * PageIndex, PageSize, DescriptionFilterText);
DomainContext.Load(query, OnExamsLoaded, null);
Run Code Online (Sandbox Code Playgroud)
然后,回调方法运行查询以获取计数.如果没有使用过滤器,我们得到所有行的计数; 如果有过滤器,那么我们得到过滤行的计数.
private void OnExamsLoaded(LoadOperation<ExamEntity> loadOperation)
{
if (loadOperation.Error != null)
{
//raise an event...
ErrorRaising(this, new ErrorEventArgs(loadOperation.Error));
}
else
{
Exams.MoveCurrentToFirst();
if (string.IsNullOrEmpty(DescriptionFilterText))
{
DomainContext.GetExamCount(OnCountCompleted, null);
}
else
{
DomainContext.GetFilteredExamCount(DescriptionFilterText, OnCountCompleted, null);
}
IsLoading = false;
}
}
Run Code Online (Sandbox Code Playgroud)
还有一个计数的回调方法:
void OnCountCompleted(InvokeOperation<int> op)
{
ItemCount = op.Value;
TotalItemCount = op.Value;
}
Run Code Online (Sandbox Code Playgroud)
设置了ItemCount后,Datapager控件会将其选中,并且我们使用过滤和智能查询进行分页,该查询仅返回要显示的记录!
LINQ使用.Skip()和.Take()简化查询.使用原始ADO.NET执行此操作更难.我通过拆分LINQ生成的查询来学习如何做到这一点.
SELECT * FROM
(select ROW_NUMBER() OVER (ORDER BY Description) as rownum, *
FROM Exams as T0 WHERE T0.Description LIKE @description ) as T1
WHERE T1.rownum between @first AND @last ORDER BY rownum
Run Code Online (Sandbox Code Playgroud)
条款"选择ROW_NUMBER()OVER(ORDER BY Description)作为rownum"是有趣的部分,因为还没有很多人使用"OVER".此子句在分配行号之前对"描述"上的表进行排序,并且在分配行号之前也应用过滤器.这允许外部SELECT在排序和过滤之后过滤行号.
所以它就是RIA Services和Silverlight中的带过滤功能的智能分页!
| 归档时间: |
|
| 查看次数: |
9169 次 |
| 最近记录: |