通过对数据进行分组、排序和筛选,以不同方式查看 DataGrid 中的数据常常很有用。若要对 DataGrid 中的数据进行分组、排序和筛选,您要将其绑定到支持这些功能的集合视图。然后,您可以在集合视图中操作这些数据,而不会影响基础数据。该集合视图中的更改将反映在 DataGrid 用户界面 (UI) 中。
PagedCollectionView 类为实现 IEnumerable 接口的数据源提供分组、排序和分页功能。
将 DataGrid 绑定到 PagedCollectionView
-
创建实现 IEnumerable 接口的数据集合。
说明: 该集合中的对象必须实现 INotifyPropertyChanged 接口和 IEditableObject 接口,以便 DataGrid 对属性更改和编辑操作正确做出响应。
-
创建 PagedCollectionView 并将数据集合传递到构造函数。
-
将 DataGrid..::..ItemsSource 属性设置为 PagedCollectionView。
// Create a collection to store task data.
ObservableCollection<Task> taskList = new ObservableCollection<Task>();
// Generate some task data and add it to the task list.
for (int i = 1; i <= 14; i++)
{
taskList.Add(new Task()
{
ProjectName = "Project " + ((i % 3) + 1).ToString(),
TaskName = "Task " + i.ToString(),
DueDate = DateTime.Now.AddDays(i),
Complete = (i % 2 == 0),
Notes = "Task " + i.ToString() + " is due on "
+ DateTime.Now.AddDays(i) + ". Lorum ipsum..."
});
}
PagedCollectionView taskListView = new PagedCollectionView(taskList);
this.dataGrid1.ItemsSource = taskListView;
为了指定项在 DataGrid 中的分组方式,使用 PropertyGroupDescription 类型对源视图中的项进行分组。
对 DataGrid 中的项分组
-
创建 PropertyGroupDescription 并将按其进行分组的属性名称传递到该构造函数。
-
将 PropertyGroupDescription 添加到 PagedCollectionView..::..GroupDescriptions 集合。
-
将 PropertyGroupDescription 的附加实例添加到 PagedCollectionView..::..GroupDescriptions 集合,以便添加更多分组级别。
if (taskListView.CanGroup == true)
{
// Group tasks by ProjectName...
taskListView.GroupDescriptions.Add(new PropertyGroupDescription("ProjectName"));
// Then group by Complete status.
taskListView.GroupDescriptions.Add(new PropertyGroupDescription("Complete"));
}
更改行组标头的外观
-
创建一个 Style,其 DataGridRowGroupHeader 为 TargetType。
-
将 Style 放入 <DataGrid.RowGroupHeaderStyles> 标记中。
<sdk:DataGrid.RowGroupHeaderStyles>
<!-- Style for groups at top level -->
<Style TargetType="sdk:DataGridRowGroupHeader">
<Setter Property="PropertyNameVisibility" Value="Collapsed" />
<Setter Property="Background" Value="#FF112255" />
<Setter Property="Foreground" Value="#FFEEEEEE" />
<Setter Property="SublevelIndent" Value="15" />
</Style>
<!-- Style for groups under the top level -->
<Style TargetType="sdk:DataGridRowGroupHeader">
<Setter Property="Background" Value="#44225566" />
</Style>
</sdk:DataGrid.RowGroupHeaderStyles>
折叠或展开行组
-
获取表示要折叠扩展开的组的 CollectionViewGroup。
说明: 从 Groups 集合中可以获取 CollectionViewGroup。或者,可以使用 GetGroupFromItem 方法获取单独的 CollectionViewGroup,如下所示。
-
若要折叠组,请将 CollectionViewGroup 传递到 CollapseRowGroup 方法。将第二个参数设置为 true 还折叠所有子组。
-
若要展开组,请将 CollectionViewGroup 传递到 ExpandRowGroup 方法。将第二个参数设置为 true 还展开所有子组。
private void CollapseButton_Click(object sender, RoutedEventArgs e)
{
PagedCollectionView pcv = dataGrid1.ItemsSource as PagedCollectionView;
try
{
foreach (CollectionViewGroup group in pcv.Groups)
{
dataGrid1.ScrollIntoView(group, null);
dataGrid1.CollapseRowGroup(group, true);
}
}
catch (Exception ex)
{
// Could not collapse group.
MessageBox.Show(ex.Message);
}
}
private void ExpandButton_Click(object sender, RoutedEventArgs e)
{
PagedCollectionView pcv = dataGrid1.ItemsSource as PagedCollectionView;
try
{
foreach (CollectionViewGroup group in pcv.Groups)
{
dataGrid1.ExpandRowGroup(group, true);
}
}
catch (Exception ex)
{
// Could not expand group.
MessageBox.Show(ex.Message);
}
}
对 DataGrid 中的项进行排序
-
创建 SortDescription 并将按其排序的属性名称传递到该构造函数。
-
将 SortDescription 添加到 PagedCollectionView..::..SortDescriptions 集合。
-
将 SortDescription 的附加实例添加到 PagedCollectionView..::..SortDescriptions 集合,以便按附加的属性进行排序。
if (taskListView.CanSort == true)
{
// By default, sort by ProjectName.
taskListView.SortDescriptions.Add(new SortDescription("ProjectName", ListSortDirection.Ascending));
}
对 DataGrid 中的项进行筛选
-
创建提供筛选逻辑的一个方法。该方法用作回调并接受类型为 Object 的参数。
-
通过设置 PagedCollectionView..::..Filter 属性将筛选器应用于数据。
-
通过将 PagedCollectionView..::..Filter 属性设置为 null,移除筛选器。
下面的示例在 CheckBox 为 Checked 时应用筛选器,并且在 CheckBox 为 Unchecked 时移除该筛选器。
private void CheckBox_Checked(object sender, RoutedEventArgs e) { PagedCollectionView pcv = this.dataGrid1.ItemsSource as PagedCollectionView; if (pcv != null && pcv.CanFilter == true) { // Apply the filter. pcv.Filter = new Predicate<object>(FilterCompletedTasks); } } private void CheckBox_Unchecked(object sender, RoutedEventArgs e) { PagedCollectionView pcv = this.dataGrid1.ItemsSource as PagedCollectionView; if (pcv != null) { // Remove the filter. pcv.Filter = null; } } public bool FilterCompletedTasks(object t) { Task task = t as Task; return (task.Complete == false); }