东莞专业网站建设推广,苏州网站,在百度上怎么发布广告,教程推广优化网站排名使用过Excel的用户都知道#xff0c;Excel可以方便的对数据进行分组#xff0c;过滤#xff0c;排序等操作#xff0c;而在WPF中#xff0c;默认提供的DataGrid只有很简单的功能#xff0c;那么如何才能让我们开发的DataGrid#xff0c;也像Excel一样具备丰富的客户端操…使用过Excel的用户都知道Excel可以方便的对数据进行分组过滤排序等操作而在WPF中默认提供的DataGrid只有很简单的功能那么如何才能让我们开发的DataGrid也像Excel一样具备丰富的客户端操作呢今天就以一个简单的小例子简述如何在WPF中实现DataGrid的过滤分组排序等功能。仅供学习分享使用如有不足之处还请指正。 涉及知识点
在本示例中涉及知识点如下所示
CollectionView CollectionView 类为实现 IEnumerable 接口的数据源提供分组和排序功能。CollectionViewSourceCollectionViewSource 类允许你从 XAML 设置 CollectionView 的属性。
注意此两个类是我们实现客户端过滤分组排序的关键。 普通绑定 1. 构建数据源 在WPF中DataGrid的ItemSource属性用于绑定数据源而数据源必须是实现IEnumerable接口的的列表类型在本示例中采用具有通知属性的列表类型ObservableCollection。当列表中元素数量发生变化时可以实时的通知DataGrid进行刷新。 1.1 创建实体 在本示例中为了测试创建Student实体模型如下所示
public class Student
{public string No { get; set; }public string Name { get; set; }public int Age { get; set; }public bool Sex { get; set; }public string Class { get; set; }
} 1.2 初始化数据源列表 在本示例采用MVVM模式开发在ViewModel中创建ObservableCollection类型的Students列表如下所示
using CommunityToolkit.Mvvm.ComponentModel;
using DemoDataGrid2.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace DemoDataGrid2.ViewModels
{public class TestWindowViewModel:ObservableObject{private ObservableCollectionStudent students;public ObservableCollectionStudent Students{get { return students; }set { SetProperty(ref students, value); }}public TestWindowViewModel(){var parentName new string[5] { 张, 王, 李, 赵, 刘 };this.Students new ObservableCollectionStudent();for (int i 0; i 100; i){Student student new Student();student.No i.ToString().PadLeft(3, 0);student.Name parentName[(i % 4)] i.ToString().PadLeft(2, A);student.Age 20 (i % 5);student.Sex i % 2 0 ? true : false;student.Class ${(i % 3)}班;this.Students.Add(student);}}}
} 注意构造函数中的方法用于创建Students列表包含100名学生分别对应不同的编号姓名年龄性别班级等信息。 2. 页面绑定 在ViewModel中创建数据源后可以在Xaml中进行绑定【语法ItemsSource{Binding Students}】如下所示
Window x:ClassDemoDataGrid2.TestWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:DemoDataGrid2mc:IgnorabledTitleDataGrid示例 Height450 Width800GridGrid.RowDefinitionsRowDefinition HeightAuto/RowDefinitionRowDefinition/RowDefinition/Grid.RowDefinitionsDockPanel Grid.Row0/DockPanelDataGrid Grid.Row1 ItemsSource{Binding Students} AutoGenerateColumnsFalse CanUserAddRowsFalse CanUserDeleteRowsFalse DataGrid.ColumnsDataGridTextColumn Header学号 Binding{Binding No} Width*/DataGridTextColumnDataGridTextColumn Header姓名 Binding{Binding Name} Width*/DataGridTextColumnDataGridTextColumn Header年龄 Binding{Binding Age} Width*/DataGridTextColumnDataGridTemplateColumn Header性别 Width*DataGridTemplateColumn.CellTemplateDataTemplateTextBlock x:NamesexTextBlock.StyleStyle TargetTypeTextBlockStyle.TriggersDataTrigger Binding{Binding Sex} ValueTrueSetter PropertyText Value男/Setter/DataTriggerDataTrigger Binding{Binding Sex} ValueFalseSetter PropertyText Value女/Setter/DataTrigger/Style.Triggers/Style/TextBlock.Style/TextBlock/DataTemplate/DataGridTemplateColumn.CellTemplate/DataGridTemplateColumnDataGridTextColumn Header班级 Binding{Binding Class} Width*/DataGridTextColumn/DataGrid.Columns/DataGrid/Grid
/Window 以下两点需要注意
在本示例中性别为bool类型要转换成汉字用到了DataTrigger。DataGrid的列可以自动生成也可以手动创建可以通过AutoGenerateColumnsFalse来设置。 3. 普通绑定示例 普通绑定示例截图如下所示 DataGrid过滤 在DataGrid中实现客户端过滤且不需要重新初始化数据源则需要用到CollectionViewSource。 1. 定义资源及绑定 将CollectionViewSource定义成一种资源并将资源的Source属性绑定到数据源再将DataGrid中的ItemSource绑定到此资源然后就可以在过滤时对资源进行过滤。
定义资源如下所示
Window.ResourcesCollectionViewSource x:KeycvStudents Source{Binding Students}/CollectionViewSource
/Window.Resources DataGrid绑定资源【语法ItemsSource{Binding Source{StaticResource cvStudents}}】如下所示
DataGrid x:NamedgStudents Grid.Row1 ItemsSource{Binding Source{StaticResource cvStudents}} AutoGenerateColumnsFalse CanUserAddRowsFalse CanUserDeleteRowsFalse DataGrid.ColumnsDataGridTextColumn Header学号 Binding{Binding No} Width*/DataGridTextColumnDataGridTextColumn Header姓名 Binding{Binding Name} Width*/DataGridTextColumnDataGridTextColumn Header年龄 Binding{Binding Age} Width*/DataGridTextColumnDataGridTemplateColumn Header性别 Width*DataGridTemplateColumn.CellTemplateDataTemplateTextBlock x:NamesexTextBlock.StyleStyle TargetTypeTextBlockStyle.TriggersDataTrigger Binding{Binding Sex} ValueTrueSetter PropertyText Value男/Setter/DataTriggerDataTrigger Binding{Binding Sex} ValueFalseSetter PropertyText Value女/Setter/DataTrigger/Style.Triggers/Style/TextBlock.Style/TextBlock/DataTemplate/DataGridTemplateColumn.CellTemplate/DataGridTemplateColumnDataGridTextColumn Header班级 Binding{Binding Class} Width*/DataGridTextColumn/DataGrid.Columns
/DataGrid 2. 过滤条件 在本示例中以性别为过滤条件当点击过滤条件时触发过滤命令如下所示
DockPanel Grid.Row0 Margin5TextBlock Text筛选条件/TextBlockTextBlock Text性别/TextBlockCheckBox Content男 IsChecked{Binding FilterM.IsMaleChecked} Command{Binding FiterSexCheckedCommand}/CheckBoxCheckBox Content女 IsChecked{Binding FilterM.IsFemaleChecked} Command{Binding FiterSexCheckedCommand}/CheckBox
/DockPanel 当用户点击时触发Command绑定的命令如下所示
private ICommand fiterSexCheckedCommand;public ICommand FiterSexCheckedCommand
{get{if (fiterSexCheckedCommand null){fiterSexCheckedCommand new RelayCommandobject(FilterSexChecked);}return fiterSexCheckedCommand;}
}private void FilterSexChecked(object obj)
{if (this.dataGrid ! null){ICollectionView cvs CollectionViewSource.GetDefaultView(this.dataGrid.ItemsSource);if (cvs ! null cvs.CanFilter){cvs.Filter (object obj) {bool flag true;bool flag1 true;bool flag2 true;var student obj as Student;if (!FilterM.IsMaleChecked){flag1 student.Sex ! true;}if (!FilterM.IsFemaleChecked){flag2 student.Sex ! false;}flag flag1 flag2;return flag;};}}
} 注意通过CollectionViewSource.GetDefaultView(this.dataGrid.ItemsSource)方法获取具有过滤功能的CollectionView类对象然后再对Filter进行委托即可。
其中FilterM是在ViewModel中声明的FilterConditionM类型的属性。
private FilterConditionM filterM;public FilterConditionM FilterM
{get { return filterM; }set { SetProperty(ref filterM, value); }
} FilterConditionM是封装的过滤条件模型类 如下所示
namespace DemoDataGrid2.Models
{public class FilterConditionM:ObservableObject{private bool isMaleChecked;public bool IsMaleChecked{get { return isMaleChecked; }set { SetProperty(ref isMaleChecked , value); }}private bool isFemaleChecked;public bool IsFemaleChecked{get { return isFemaleChecked; }set { SetProperty(ref isFemaleChecked, value); }}}
} 3. 过滤功能示例 具备过滤功能的示例截图如下所示 DataGrid分组 在WPF中实现DataGrid的分组也是通过CollectionViewSource来实现。 1. 设置分组列 有两种方式可以设置分组 1.1 XAML中设置 在XAML中通过设置CollectionViewSource的GroupDescriptions属性来设置具体分组的列属性如下所示
CollectionViewSource x:KeycvStudents Source{Binding Students}CollectionViewSource.GroupDescriptionsPropertyGroupDescription PropertyNameClass/PropertyGroupDescription PropertyNameSex//CollectionViewSource.GroupDescriptions
/CollectionViewSource 1.2 后台代码设置 在ViewModel中设置CollectionView的GroupDescriptions属性如下所示
ICollectionView cvTasks CollectionViewSource.GetDefaultView(this.dataGrid.ItemsSource);
if (cvTasks ! null cvTasks.CanGroup true)
{cvTasks.GroupDescriptions.Clear();cvTasks.GroupDescriptions.Add(new PropertyGroupDescription(Class));cvTasks.GroupDescriptions.Add(new PropertyGroupDescription(Sex));
} 2. 设置分组样式 在WPF中通过设置DataGrid的GroupStyle属性来改变分组样式如下所示
DataGrid x:NamedgStudents Grid.Row1 ItemsSource{Binding Source{StaticResource cvStudents}} AutoGenerateColumnsFalse CanUserAddRowsFalse CanUserDeleteRowsFalse DataGrid.GroupStyle!-- 第一层分组 --GroupStyleGroupStyle.ContainerStyleStyle TargetType{x:Type GroupItem}Setter PropertyMargin Value0,0,0,5/Setter PropertyTemplateSetter.ValueControlTemplate TargetType{x:Type GroupItem}Expander IsExpandedTrue BackgroundLightGray BorderBrush#FF002255 ForegroundDarkBlue BorderThickness1Expander.HeaderDockPanelTextBlock FontWeightBold Text{Binding PathName} Margin5/TextBlock FontWeightBold Text 班 , VerticalAlignmentCenter/TextBlockTextBlock FontWeightBold Text{Binding PathItemCount} VerticalAlignmentCenter/TextBlock FontWeightBold Text 名学生 VerticalAlignmentCenter/TextBlock/DockPanel/Expander.HeaderExpander.ContentItemsPresenter //Expander.Content/Expander/ControlTemplate/Setter.Value/Setter/Style/GroupStyle.ContainerStyle/GroupStyle!-- 第二层及之后的分组 --GroupStyleGroupStyle.HeaderTemplateDataTemplateDockPanel BackgroundLightGoldenrodYellowTextBlock ForegroundBlue Margin30,0,0,0 Width30TextBlock.StyleStyle TargetTypeTextBlockStyle.TriggersDataTrigger Binding{Binding PathName} ValueTrueSetter PropertyText Value男/Setter/DataTriggerDataTrigger Binding{Binding PathName} ValueFalseSetter PropertyText Value女/Setter/DataTrigger/Style.Triggers/Style/TextBlock.Style/TextBlockTextBlock Text{Binding PathItemCount} ForegroundBlue//DockPanel/DataTemplate/GroupStyle.HeaderTemplate/GroupStyle/DataGrid.GroupStyleDataGrid.ColumnsDataGridTextColumn Header学号 Binding{Binding No} Width*/DataGridTextColumnDataGridTextColumn Header姓名 Binding{Binding Name} Width*/DataGridTextColumnDataGridTextColumn Header年龄 Binding{Binding Age} Width*/DataGridTextColumnDataGridTemplateColumn Header性别 Width*DataGridTemplateColumn.CellTemplateDataTemplateTextBlock x:NamesexTextBlock.StyleStyle TargetTypeTextBlockStyle.TriggersDataTrigger Binding{Binding Sex} ValueTrueSetter PropertyText Value男/Setter/DataTriggerDataTrigger Binding{Binding Sex} ValueFalseSetter PropertyText Value女/Setter/DataTrigger/Style.Triggers/Style/TextBlock.Style/TextBlock/DataTemplate/DataGridTemplateColumn.CellTemplate/DataGridTemplateColumnDataGridTextColumn Header班级 Binding{Binding Class} Width*/DataGridTextColumn/DataGrid.Columns
/DataGrid DataGrid排序 在WPF中实现DataGrid的排序也是通过CollectionViewSource来实现。 1. 设置排序列 有两种方式可以设置DataGrid排序列如下所示 1.1 XAML中设置 通过设置CollectionViewSource的SortDescriptions属性设置排序列和排序方向。如下所示
CollectionViewSource x:KeycvStudents Source{Binding Students}CollectionViewSource.SortDescriptionsscm:SortDescription PropertyNameNo DirectionAscending/scm:SortDescription PropertyNameAge DirectionDescending//CollectionViewSource.SortDescriptions
/CollectionViewSource 其中scm是新定义的命名空间【xmlns:scmclr-namespace:System.ComponentModel;assemblyWindowsBase】 1.2 后台代码设置 在ViewModel中通过后台代码设置同样也需要引入对应的命名空间如下所示
ICollectionView cvTasks CollectionViewSource.GetDefaultView(this.dataGrid.ItemsSource);
if (cvTasks ! null cvTasks.CanSort true)
{cvTasks.SortDescriptions.Clear();cvTasks.SortDescriptions.Add(new SortDescription(No, ListSortDirection.Ascending));cvTasks.SortDescriptions.Add(new SortDescription(Age, ListSortDirection.Ascending));
} DataGrid整体示例 具备过滤分组排序的示例截图如下所示 参考文献 1. 官方文档https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/controls/how-to-group-sort-and-filter-data-in-the-datagrid-control?viewnetframeworkdesktop-4.8 以上就是【浅谈WPF之DataGrid过滤分组排序】的全部内容希望能够一起学习共同进步。