CollectionView

集合视图

什么是集合视图

WPF具有强有力的数据绑定机制。它允许你直接地绑定几乎任意集合到视图上。但是当你想要排序、筛选和分组,这方面的支持几乎是没有的。这就是CollectionView发挥作用的地方。一个集合视图是针对集合提供附加特性(导航、排序、筛选和分组)的包装器。

如何创建和使用集合视图

下面的例子展示了你该如何创建一个集合视图并且绑定它到ListBox上。

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</Window>        
public class CustomerView
{
    public CustomerView()
    {
        DataContext = new CustomerViewModel();
    }
}

public class CustomerViewModel
{
    private ICollectionView _customerView;
    public ICollectionView Customers
    {
        get { return _customerView; }
    }

    public CustomerViewModel()
    {
        IList<Customer> customers = new GetCustomers();
        _customerView = CollectionViewSource.GetDefaultView(customers);
    }
}

导航

集合视图添加了针对选择追踪的支持。如何你在绑定了集合的视图上设置IsSynchronizedWithCurrentItem属性为True,它将会自动地同步集合视图的当前项。

<ListBox ItemSource={Binding Customers} IsSynchronizedWithCurrentItem="True"/>

如果你正在使用MVVM设计模式,你不必要额外地写控件的SelectedItem,因为它在集合视图上是隐含的。

IList<Customer> customers = GetCustomers();
ICollectionView _customerView = CollectionViewSource.GetDefaultView(customers);
_customerView.CurrentChanged = CustomerSelectionChanged.

private CustomerSelectionChanged(object sender, EventArgs e)
{
    //重写选择改变
}

在集合石图上,你也可以从ViewModel中通过调用MoveCurrentToFirst函数或者MoveCurrentToList函数手动地控制选中。

筛选

为了筛选集合视图,你可以定义一个回调方法决定他们是否应该是视图的一部分。方法应该具有下列签名bool Filter(object item)。现在将你的方法设置到集合视图的Filter委托类型的属性上就可以了。

ICollectionView _customerView = CollectionViewSource.GetDefaultView(customers);
_customerView.Filter = CustomerFilter;

private bool CustomerFilter(object)
{
    Customer customer = item as Customer;
    return customer.Name.Contain(_filterString);
}

刷新筛选

如果你改变了筛选规则,并且你想要刷新视图,你应该调用集合视图的Refresh函数。

public string FilterString
{
    get {return _filterString; }
    set 
    { 
        _filterString = value;
        NotifyPropertyChanged("FilterString");
        _customerView.Refresh();
    }
}

排序

升序或者降序地排序数据通过一个或者多个规则是通用的需求对于浏览数据。集合视图让他变得更加容易实现这个目标。只要添加SortDescriptions到集合视图即可。

ICollectionView _customer = CollectionViewSource.GetDefaultView(customers);
_customerView.SortDescriptions.Add(new SortDescription("LastName", ListSortDirection.Ascending));
_customerView.SortDescriptions.Add(new SortDescription("FirstName", ListSortDirection.Ascending));

快速排序

上面介绍的排序技术很简单,但是对于大量数据来说这是非常慢的,因为它内部使用了反射。但它是可选的,更高性能的方法是通过提供自定义排序类。

ListCollectionView _customerView = CollectionViewSource.GetDefaultView(customers);
_customerView.CustomSort = new CustomerSorter();

public class CustomerSorter : IComparer
{
    public int Compare(object x, object y)
    {
        Customer custX = x as Customer;
        Customer custY = y as Customer;
        return custX.Name.CompareTo(custY.Name);
    }
}

分组

分组是集合视图的另一个强有力的特性。你可以定义许多组,只需要添加GroupDescriptions到集合视图。
注意:分组关闭虚拟化。在大数据集时这可能带来大量的性能问题。所以小心使用它。

ICollectionView _customerView = CollectionViewSOurce.getDefaultView(customers);
_customerView.GroupDescriptions.Add(new PropertyGroupDescription("Country"));

为了确保分组在视图中的可见性,你必须定义一个特别的GroupStyle在视图中。

<ListBox ItemSource="{Binding Customers}">
    <ListBox.GroupStyle>
        <GroupStyle.HeaderTemplate>
            <DatatTemplate>
                <TextBlock Text="{Binding Path=Name}"/>
            </DatatTemplate>
        </GroupStyle.HeaderTemplate>
    </ListBox.GroupStyle>
</List>

如何在XAML中创建一个集合视图

在XAML中创建集合视图也是可能的。

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Window.Resources>
        <CollectionViewSource Source="{Binding}" x:Key="customerView"> 
            </CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="Country"/>
            </CollectionView.Source.GroupDescriptions>
        </CollectionViewSource>
    </Window.Resources>
</Window>
posted @ 2023-08-18 15:38  Juston007  阅读(45)  评论(0)    收藏  举报