速看!DataGrid 居然能这么分组

 速看!DataGrid 居然能这么分组

本文经原作者授权以原创方式二次分享,欢迎转载、分享。

作者:ARM830

原文链接:   https://www.cnblogs.com/T-ARF/p/16295094.html 分组和树形结构是不一样的。

二次编辑:驚鏵

树形结构是以递归形式存在。分组是以键值对存在的形式,类似于GroupBy这样的形式。

举个例子

速看!DataGrid 居然能这么分组

当以Sex为分组依据时则是

速看!DataGrid 居然能这么分组

那么,我们如何在WPF使用呢?当然了 我们在WPF中的表现形式和图表稍微不同的。

首先,我们介绍如何分组。

我们的数据模型如下

public enum Sex
    {
        男,
        女
    }
    public class Test
    {
        public string Name { getset; }
        public int Id { getset; }
        public Sex SexType { getset; }
        public int Class { getset; }
    }

非常的简单,下面的代码是我们的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 居然能这么分组

当我们创建完分组后,则是布局

剩下就布局了。

布局就是(Datagrid,Listbox.).GroupStyle了,

其中

Panel属性是决定布局面板的,通常与你使用GroupStyle的空间有关。

DataGridGroupStylePanel使用DataGridRowsPresenter

因为Panel属性默认是StackPanel,所以DataGrid使用分组时,列的宽度设定为*时 可能出现错误。

所以要注意

ContainerStyle是决定生成GroupItem的样式,通常自己发挥就好了

由于分组之后的集合的类型是微软内部类。

最常用的属性

Name

Items

对应我图表中的KeyValue,换据说在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>

再稍微修改下样式,于是乎我们得到了这样的画面

速看!DataGrid 居然能这么分组

因为我们是通过expander修改而成,如果想要更加细微的画面,建议自定义控件。

具体代码请参考源代码[1]

参考资料

[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

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!