WPF Samples中的示例
在WPF Samples中有一个关于Grouping的Demo。
该Demo结构如下:

MainWindow.xaml如下:
Pick up Groceries and Detergent
Do Laundry
Email Clients
Clean my office
Get ready for family reunion
Review new budget proposals
Group by task type
其中:
Pick up Groceries and Detergent
Do Laundry
Email Clients
Clean my office
Get ready for family reunion
Review new budget proposals
使用XmlDataProvider来加载和绑定XML数据。
将MyTasks绑定到ItemsControl。
设置数据模板。
跟本次介绍的主题Grouping有关的内容如下:

ItemsControl.GroupStyle获取定义每个级别的组的外观的 GroupStyle 对象集合。
GroupStyle如下所示:
public class GroupStyle : INotifyPropertyChanged
{
public static readonly ItemsPanelTemplate DefaultGroupPanel;
public GroupStyle();
public static GroupStyle Default { get; }
[DefaultValue(0)]
public int AlternationCount { get; set; }
[DefaultValue(null)]
public Style ContainerStyle { get; set; }
[DefaultValue(null)]
public StyleSelector ContainerStyleSelector { get; set; }
[DefaultValue(null)]
public string HeaderStringFormat { get; set; }
[DefaultValue(null)]
public DataTemplate HeaderTemplate { get; set; }
[DefaultValue(null)]
public DataTemplateSelector HeaderTemplateSelector { get; set; }
[DefaultValue(false)]
public bool HidesIfEmpty { get; set; }
public ItemsPanelTemplate Panel { get; set; }
protected event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e);
}
}
这里设置了GroupStyle.HeaderTemplate,这个元素定义了分组头的数据模板。数据模板决定了分组头的具体显示方式。
这里的Name指的是CollectionViewGroup 类的Name属性。

CollectionViewGroup 类表示根据 GroupDescriptions 由 CollectionView 对象创建的组。
MainWindow.cs如下:
public partial class MainWindow : Window
{
private CollectionView _myView;
public MainWindow()
{
InitializeComponent();
}
private void AddGrouping(object sender, RoutedEventArgs e)
{
_myView = (CollectionView) CollectionViewSource.GetDefaultView(myItemsControl.ItemsSource);
if (_myView.CanGroup)
{
var groupDescription
= new PropertyGroupDescription("@Type");
_myView.GroupDescriptions.Add(groupDescription);
}
}
private void RemoveGrouping(object sender, RoutedEventArgs e)
{
_myView = (CollectionView) CollectionViewSource.GetDefaultView(myItemsControl.ItemsSource);
_myView.GroupDescriptions.Clear();
}
}
只包含两个事件处理程序。
进行分组是这样写的:
private void AddGrouping(object sender, RoutedEventArgs e)
{
_myView = (CollectionView) CollectionViewSource.GetDefaultView(myItemsControl.ItemsSource);
if (_myView.CanGroup)
{
var groupDescription
= new PropertyGroupDescription("@Type");
_myView.GroupDescriptions.Add(groupDescription);
}
}
_myView = (CollectionView) CollectionViewSource.GetDefaultView(myItemsControl.ItemsSource);
虽然CollectionViewSource本身不是一个静态类,但它提供了一个静态方法GetDefaultView,这个方法用于获取与特定数据源关联的默认视图。这种设计允许开发者不必实例化CollectionViewSource对象就能访问和操作数据源的视图。

var groupDescription
= new PropertyGroupDescription("@Type");
_myView.GroupDescriptions.Add(groupDescription);

PropertyGroupDescription类描述使用属性名作为条件对项进行分组。
使用的是这个构造函数:

= new PropertyGroupDescription("@Type");
在XML和XPath的上下文中,@符号用于引用元素的属性。
这样就实现了基于Type属性进行分组。
private void RemoveGrouping(object sender, RoutedEventArgs e)
{
_myView = (CollectionView) CollectionViewSource.GetDefaultView(myItemsControl.ItemsSource);
_myView.GroupDescriptions.Clear();
}
取消分组将_myView.GroupDescriptions清空即可。
该Demo的效果如下:

分组前:

分组后:

代码来源
[WPF-Samples/Data Binding/Grouping at main · microsoft/WPF-Samples (github.com)]
欢迎关注微信公众号:DotNet学习交流。