速看!DataGrid 居然能这么分组
本文经原作者授权以原创方式二次分享,欢迎转载、分享。
作者:ARM830
原文链接: https://www.cnblogs.com/T-ARF/p/16295094.html 分组和树形结构是不一样的。
二次编辑:驚鏵
树形结构是以递归形式存在。分组是以键值对存在的形式,类似于GroupBy这样的形式。
举个例子

当以Sex为分组依据时则是

那么,我们如何在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分组依据:

当我们创建完分组后,则是布局
剩下就布局了。
布局就是(Datagrid,Listbox.).GroupStyle了,
其中
Panel属性是决定布局面板的,通常与你使用GroupStyle的空间有关。
DataGrid的GroupStyle的Panel使用DataGridRowsPresenter
因为Panel属性默认是StackPanel,所以DataGrid使用分组时,列的宽度设定为*
时 可能出现错误。
所以要注意
ContainerStyle是决定生成GroupItem的样式,通常自己发挥就好了
由于分组之后的集合的类型是微软内部类。
最常用的属性
Name
Items
对应我图表中的Key和Value,换据说在ContainerStyle中你只有这两个常用属性可以绑定,Items是你分组后 ,你自己的类型的集合,这个时候就可以使用你自己的属性进行绑定了。
GroupStyle属性是一个集合,可以存在多个子项,子项的名称也是GroupStyle.
多个子项是对应不同的分级,既第一个子项对应第一层分组,第二对应第二层。
于是乎
我们给出这样的布局
<wpfdev:Window x:Class="分组.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wpfdev="https://github.com/WPFDevelopersOrg/WPFDevelopers"
xmlns:local="clr-namespace:分组"
mc:Ignorable="d"
Title="ARM830 - 分组" Height="450" Width="800">
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<Window.Resources>
<CollectionViewSource x:Key="cvs" Source="{Binding Model}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="SexType"/>
<PropertyGroupDescription PropertyName="Class"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Window.Resources>
<Grid>
<DataGrid HeadersVisibility="All"
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="Margin" Value="0,0,0,0"/>
<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>
</Grid>
</wpfdev:Window>
再稍微修改下样式,于是乎我们得到了这样的画面

因为我们是通过expander修改而成,如果想要更加细微的画面,建议自定义控件。
具体代码请参考源代码[1]
参考资料
源代码: https://files-cdn.cnblogs.com/files/T-ARF/%E5%88%86%E7%BB%84.zip?t=1653115965
原文始发于微信公众号(WPF开发者):速看!DataGrid 居然能这么分组
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/55046.html