WPF 分组
分组和树形结构是不一样的。
树形结构是以递归形式存在。分组是以键值对存在的形式,类似于GroupBy这样的形式。
举个例子
ID | NAME | SEX | Class |
1 | 张三 | 男 | 1 |
2 | 李四 | 女 | 2 |
3 | 王二 | 男 | 1 |
当以Sex为分组依据时则是
Key | Value | |||
男 | 1 | 张三 | 男 | 1 |
3 | 王二 | 男 | 1 | |
女 | 2 | 李四 | 女 | 2 |
那么,我们如何在WPF使用呢?当然了 我们在WPF中的表现形式和图表稍微不同的。
首先,我们介绍如何分组。
我们的数据模型如下
public enum Sex { 男, 女 } public class Test { public string Name { get; set; } public int Id { get; set; } public Sex SexType { get; set; } public int Class { get; set; } }
非常的简单,下面的代码是我们的ViewModel
public class ViewModel { public ViewModel() { for (int i = 0; i < 10; i++) { Test t = new Test(); t.Class = i % 2 == 0 ? 1 : 2; t.Id = i * 100; t.Name = "Name" + i; t.SexType = i % 2 == 0 ? Sex.男 : Sex.女; Model.Add(t); }
for (int i = 0; i < 10; i++) { Test t = new Test(); t.Class = i % 2 == 0 ? 3 : 4; t.Id = i * 200; t.Name = "Name" + i; t.SexType = i % 2 == 0 ? Sex.男 : Sex.女; Model.Add(t); } } private ObservableCollection<Test> mode = new ObservableCollection<Test>(); public ObservableCollection<Test> Model { get { return mode; } set { mode = value; } } }
就是简单的添加一些数据。
我们的前台界面上就是datagrid。
然后是最重要的分组xaml代码
<CollectionViewSource x:Key="cvs" Source="{Binding Model}"> <CollectionViewSource.GroupDescriptions> <PropertyGroupDescription PropertyName="SexType"/> <PropertyGroupDescription PropertyName="Class"/> </CollectionViewSource.GroupDescriptions> </CollectionViewSource>
Groupscriptptions内就是我们分组依据。
PropertyName是分组依据,是集合内的属性。
当我们添加了多个参数就还会产生层级分组,就是上一个分组基础上再次分组。
比如我们最开始的数据多次分组。
一开始SEX,我们再加上一个class分组依据:
Key | Value | ||||
男 | Key | value | |||
1 | 1 | 张三 | 男 | 1 | |
3 | 王二 | 男 | 1 | ||
女 | Key | value | |||
2 | 2 | 李四 | 女 | 2 |
当我们创建完分组后,则是布局
剩下就布局了。
布局就是(Datagrid,Listbox.).GroupStyle了,
其中
Panel属性是决定布局面板的,通常与你使用GroupStyle的空间有关。
DataGrid的GroupStyle的Panel使用DataGridRowsPresenter
因为Panel属性默认是StackPanel,所以DataGrid使用分组时,列的宽度设定为*时 可能出现错误。
所以要注意
ContainerStyle是决定生成GroupItem的样式,通常自己发挥就好了
由于分组之后的集合的类型是微软内部类。
最常用的属性
Name
Items
对应我图表中的Key和Value,换据说在ContainerStyle中你只有这两个常用属性可以绑定,Items是你分组后 ,你自己的类型的集合,这个时候就可以使用你自己的属性进行绑定了。
GroupStyle属性是一个集合,可以存在多个子项,子项的名称也是GroupStyle.
多个子项是对应不同的分级,既第一个子项对应第一层分组,第二对应第二层。
于是乎
我们给出这样的布局
<DataGrid HeadersVisibility="None" AutoGenerateColumns="False" CanUserAddRows="False" ItemsSource="{Binding Source={StaticResource cvs}}"> <DataGrid.GroupStyle> <GroupStyle> <GroupStyle.Panel> <ItemsPanelTemplate> <DataGridRowsPresenter/> </ItemsPanelTemplate> </GroupStyle.Panel> <GroupStyle.ContainerStyle> <Style TargetType="GroupItem"> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <Expander ExpandDirection="Right" Header="{Binding Name}" IsExpanded="True"> <ItemsPresenter/> </Expander> </ControlTemplate> </Setter.Value> </Setter> </Style> </GroupStyle.ContainerStyle> </GroupStyle> <GroupStyle> <GroupStyle.ContainerStyle> <Style TargetType="GroupItem"> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <Border> <Expander ExpandDirection="Down" Header="{Binding Name}" IsExpanded="True"> <Expander.HeaderTemplate> <DataTemplate> <Grid Background="Yellow" > <TextBlock > <Run Text="班级:"/> <Run Text="{Binding Mode=OneWay}"/> </TextBlock> </Grid> </DataTemplate> </Expander.HeaderTemplate> <ItemsPresenter/> </Expander> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </GroupStyle.ContainerStyle> </GroupStyle> </DataGrid.GroupStyle> <DataGrid.Columns> <DataGridTextColumn Width="*" Header="姓名" Binding="{Binding Name}"/> <DataGridTextColumn Width="*" Header="性别" Binding="{Binding SexType}"/> <DataGridTextColumn Width="*" Header="Id" Binding="{Binding Id}"/> </DataGrid.Columns> </DataGrid>
再稍微修改下样式,于是乎我们得到了这样的画面
因为我们是通过expander修改而成,如果想要更加细微的画面,建议自定义控件。
具体代码请参考源代码
相关文章
- 3D视频聊天、百万比特量子计算机、十倍性能TPU:谷歌在I/O大会上让我们看到了未来
- 为什么 .NET的反射这么慢?
- ASP.NET Core 单元测试之如何 Mock HttpClient.GetStringAsync()
- 在ASP.NET Core中使用百度在线编辑器UEditor
- MVC路由自定义及视图找寻规则
- Microsoft 宣布将停止支持多个 .NET Framework 版本
- ASP.NET Core 单元测试:如何Mock Url.Page()
- 使用AJAX获取Django后端数据
- 一图看懂 ASP.NET Core 中的服务生命周期
- 构建高性能ASP.NET应用的12点建议
- 你了解AJAX吗?TA不是新编程语言而是WEB应用程序技术
- 又一起.NET程序挂死, 用 Windbg 抽丝剥茧式的真实案例分析
- 从一个Demo开始,揭开Netty的神秘面纱
- 从.net转型,聊聊最近一些面试,薪资和想法
- 如何在 ASP.NET Core 中使用内置的 Json 格式化日期 ?
- ASP.NET 5 开发者的五个阶段​​
- 让编程更轻松的 7 个 Visual Studio 扩展
- 对 ASP.NET 异步编程的一点理解
- 推荐 7 款好用的 Visual Studio 扩展
- 我们从2021谷歌I/O大会给的谜题中发现了隐藏信息