当绑定源是集合时,WPF实际用的是CollectionView进行绑定。
集合视图是位于绑定源集合顶部的一层,您可以通过它使用排序、筛选和分组查询来导航和显示源集合,而无需更改基础源集合本身。集合视图还维护着一个指向集合中的当前项的指针。如果源集合实现了INotifyCollectionChanged接口,则CollectionChanged 事件引发的更改将传播到视图。
在代码中可以通过CollectionViewSource.GetDefaultView得到ICollectionView接口,进行操作视图。
比如
ICollectionView view = CollectionViewSource.GetDefaultView(
this.FindResource(“photos”));
GetDefaultView的参数是object,也就是源。
排序
ICollectionView view = CollectionViewSource.GetDefaultView(
this.FindResource(“photos”));
view.SortDescriptions.Add(new SortDescription(
propertyName, ListSortDirection.Descending));
SortDescriptions是SortDescriptionCollection类型,支持Add, Remove, Clear等Collection通用的方法。可以加入多个SortDescription,就像SQL时的order by 一样。
TIP:
定制自己的排序规则:
如果collection实现了IList接口(大部分系统自带collection都实现了此接口),可以把ICollectionView转化成ListCollectionView,该类有一个叫CustomSort的属性,是个IComparer接口,自己实现一个继承此接口的类,并赋给CustomSort即可。
分组
// Get the default view
ICollectionView view = CollectionViewSource.GetDefaultView(
this.FindResource(“photos”));
// Do the grouping
view.GroupDescriptions.Clear();
view.GroupDescriptions.Add(new PropertyGroupDescription(“DateTime”));
虽然上面代码实现了分组,但是界面上还是显示在一起的,没有区分出来,我们需要明确的分隔出各个组,可以利用ItemsControl.GroupStyle,定义DataTemplate区分出各个组。
<ListBox.GroupStyle> <GroupStyle> <GroupStyle.HeaderTemplate> <DataTemplate> <Border BorderBrush="Black" BorderThickness="1"> <TextBlock Text="{Binding Path=Name}" FontWeight="Bold"/> </Border> </DataTemplate> </GroupStyle.HeaderTemplate> </GroupStyle> </ListBox.GroupStyle>
筛选
ICollectionView view = CollectionViewSource.GetDefaultView(this.FindResource
(“photos”));
view.Filter = delegate(object o) {
return ((o as Photo).DateTime - DateTime.Now).Days <= 7;
};
Filter是一个delegate,Predicate<object>,接收object为参数,返回bool值。
上一下\下一个
void previous_Click(object sender, RoutedEventArgs e) { // Get the default view ICollectionView view = CollectionViewSource.GetDefaultView( this.FindResource(“photos”)); // Move backward view.MoveCurrentToPrevious(); // Wrap around to the end if (view.IsCurrentBeforeFirst) view.MoveCurrentToLast(); } void next_Click(object sender, RoutedEventArgs e) { // Get the default view ICollectionView view = CollectionViewSource.GetDefaultView( this.FindResource(“photos”)); // Move forward view.MoveCurrentToNext(); // Wrap around to the beginning if (view.IsCurrentAfterLast) view.MoveCurrentToFirst(); }
Xaml中使用视图
SortDescriptions需要加入以下命名空间:xmlns:componentModel=”clr-namespace:System.ComponentModel;assembly=WindowsBase”
这里Filter是一个事件,需要在后台代码中实现,不像上面的是个delegate
void viewSource_Filter(object sender, FilterEventArgs e)
{
e.Accepted = ((e.Item as Photo).DateTime - DateTime.Now).Days <= 7;
}