How to Navigate, Group, Sort and Filter Data in WPF

本文详细介绍了WPF中CollectionView的功能,包括导航、排序、过滤和分组等特性,并提供了具体的实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

What is a CollectionView?

WPF has a powerful data binding infrastructure. It allows you to bind almost any kind of collection directly to a view. But when it comes to sorting, filtering and grouping the support of the collections is rare. That's the point where theCollectionView comes into play. A collection view is a wrapper around a collection that provides the following additional features:

  • Navigation
  • Sorting
  • Filtering
  • Grouping

How to Create and Use a CollectionView

The following example shows you how to create a collection view and bind it to a ListBox

 
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ListBox ItemsSource={Binding Customers} />
</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 = GetCustomers();
        _customerView = CollectionViewSource.GetDefaultView(customers);
    }
}
 
 

Navigation

The collection view adds support for selection tracking. If you set the propertyIsSynchronizedWithCurrentItem to True on the view that the collection is bound to, it automatically synchronizes the current item of the CollectionView and the View.

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

If you are using a MVVM (Model-View-ViewModel) pattern, you don't have to extra wire-up theSelectedItem of the control, because it's implicity available over the CollectionView.

 
IList<Customer> customers = GetCustomers();
ICollectionView _customerView = CollectionViewSource.GetDefaultView(customers);
_customerView.CurrentChanged = CustomerSelectionChanged;
 
private CustomerSelectionChanged(object sender, EventArgs e)
{
  // React to the changed selection
}
 
 

You can also manually control the selection from the ViewModel by calling the MoveCurrentToFirst() or MoveCurrentToLast() methods on the CollectionView.

Filtering

To filter a collection view you can define a callback method that determines if the item should be part of the view or not. That method should have the following signature:bool Filter(object item). Now set the delegate of that method to theFilter property of the CollectionView and you're done.

 
ICollectionView _customerView = CollectionViewSource.GetDefaultView(customers);
_customerView.Filter = CustomerFilter
 
private bool CustomerFilter(object item)
{
    Customer customer = item as Customer;
    return customer.Name.Contains( _filterString );
}
 
 

Refresh the filter

If you change the filter criteria and you want to refresh the view, you have to callRefresh() on the collection view

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

Sorting

Sorting data ascending or descending by one or multiple criterias is a common requirement for viewing data. The collection view makes it so easy to achieve this goal. Just add as manySortDescriptions as you like to the CollectionView

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

Fast Sorting

The sorting technique explained above is really simple, but also quite slow for a large amount of data, because it internally uses reflection. But there is an alternative, more performant way to do sorting by providing a custom sorter.

 
ListCollectionView _customerView = CollectionViewSource.GetDefaultView(customers);
                                         as ListCollectionView;
_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);
    }
}
 
 

Grouping

Grouping is another powerful feature of the CollectionView. You can define as many groups as you like by addingGroupDescriptions to the collection view.

Note: Grouping disables virtualization! This can bring huge performance issues on large data sets. So be careful when using it.

 
ICollectionView _customerView = CollectionViewSource.GetDefaultView(customers);
_customerView.GroupDescriptions.Add(new PropertyGroupDescription("Country"));
 
 

To make the grouping visible in the view you have to define a special GroupStyle on the view.

 
<ListBox ItemsSource="{Binding Customers}">
    <ListBox.GroupStyle>
        <GroupStyle.HeaderTemplate>
            <DataTemplate>
              <TextBlock Text="{Binding Path=Name}"/>
            </DataTemplate>
          </GroupStyle.HeaderTemplate>
    </ListBox.GroupStyle>
</ListBox>
 
 

How to create a CollectionView in XAML

It's also possible to create a CollectionView completely in 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" />
           </CollectionViewSource.GroupDescriptions>
        </CollectionViewSource>
    </Window.Resources>
    <ListBox ItemSource="{Binding Source={StaticResource customerView}}" />
</Window>
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值