WPF中数据视图提供了许多功能,如过滤、排序、分组等,这里简单介绍其使用方法。
- 过滤
在将集合作为数据源时,可使用视图对象的Filter属性设置过滤器,Filter属性接收一个Predicate委托,委托指向自定义的筛选方法:
过滤器依次检查数据源集合中的第一项,满足过滤条件,则返回true,不满足返回false。
ListCollectionView view = (ListCollectionView)CollectionViewSource.GetDefaultView(this.ProductList);
view.Filter = new Predicate<object>(DoFilter);
- 排序
最简单的方法是根据每个数据项中的一个或多个属性的值进行排序,使用System.ComponentModel.SortDescription对象确定希望使用的字段及排序方向(升序或降序):
ListCollectionView view = (ListCollectionView)CollectionViewSource.GetDefaultView(this.ProductList);
view.SortDescriptions.Add(new SortDescription("PropertyName", ListSortDirection.Ascending));
view.SortDescriptions.Add(new SortDescription("PropertyName1", ListSortDirection.Ascending));
默认的排序规则是按字母或数字顺序,当然也可执行自定义排序,但只能应用于ListCollectionView视图,不能应用于BindingListCollectionView视图。ListCollectionView类的CustomSort接收一个IComparer对象。下面是一个DataGrid控件列头手动排序的简单示例:
((ListCollectionView)SeriesListView).CustomSort = new ProductComparer(ListSortDirection.Ascending);
public class ProductComparer : IComparer
{
private readonly ListSortDirection _sortDirection;
public ProductComparer(ListSortDirection direction)
{
this._sortDirection = direction;
}
public int Compare(object x, object y)
{
Product xSeries = x as Product;
Product ySeries = y as Product;
int flag = _sortDirection == ListSortDirection.Ascending ? 1 : -1;
int result;
//具体的比较规则
return flag * result;
}
}
- 分组
以简单的方式进行分组:
ListCollectionView view = (ListCollectionView)CollectionViewSource.GetDefaultView(this.ProductList);
view.SortDescriptions.Add(new SortDescription("PropertyName", ListSortDirection.Ascending));
view.GroupDescriptions.Add(new PropertyGroupDescription("GroupPropertyName"));
- 在当前视图的过滤、排序、分组条件条件发生变化时,需要调用ICollectionViewSource.Refresh()方法,重新刷新视图。但在某些场景下,更改捕获困难,如某处程序更改了数据源中某项数据的某个属性值(过滤等条件未变化),导致该项数据不再满足筛选条件,但若未调用Refresh()方法强制执行更新,会导致看不到变化。
WPF4.5引入了“实时成型”功能,通过监视特定属性的变化,来触发刷新操作,但增加了额外开销。
对于ObservableCollection类型的数据源,通过IsLiveFiltering属性打开实时成型功能,通过LiveFilteringProperties属性设置需要监视的属性:
ListCollectionView view = (ListCollectionView)CollectionViewSource.GetDefaultView(this.ProductList);
view.IsLiveFiltering = true;
view.LiveFilteringProperties.Add("PropertyName");