首页 > 编程语言 >WPF/C#:显示分组数据的两种方式

WPF/C#:显示分组数据的两种方式

时间:2024-06-19 13:10:42浏览次数:27  
标签:控件 Name People C# 分组 new WPF Class

前言

本文介绍自己在遇到WPF对数据进行分组显示的需求时,可以选择的两种方案。一种方案基于ICollectionView,另一种方案基于IGrouping

基于ICollectionView实现

相关cs代码:

[ObservableProperty]
private ObservableCollection<People> people;

public GroupDemoViewModel()
{
    People = new ObservableCollection<People>
    {
        new People { Name = "小一", Class = "1班" },
        new People { Name = "小二", Class = "2班" },
        new People { Name = "王五", Class = "1班" },
        new People { Name = "小红", Class = "2班" },
        new People { Name = "小绿", Class = "1班" },
        new People { Name = "小刚", Class = "2班" },
    };
   
    MyView = CollectionViewSource.GetDefaultView(People);
    var groupDescription
        = new PropertyGroupDescription("Class");
    MyView.GroupDescriptions.Add(groupDescription); 
}

这段代码使用了WPF中的CollectionViewSourcePropertyGroupDescription类来对数据进行分组。

CollectionViewSource是一个用于提供数据视图的类,它允许你对数据进行排序、筛选和分组。

GetDefaultView方法返回一个默认视图,该视图是对People集合的包装。这个视图可以用于在UI中显示数据,并且可以应用各种视图操作(如排序、筛选和分组)。

PropertyGroupDescription是一个用于定义分组规则的类。这里创建了一个新的PropertyGroupDescription对象,并指定分组依据的属性为Class,这意味着数据将根据这意味着数据将根据People集合中每个对象的Class属性值进行分组。

xaml相关代码:

<ui:ListView ItemsSource="{Binding MyView}">
    <ui:ListView.ItemTemplate>
        <DataTemplate >
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}" Margin="5"/>
                <TextBlock Text="{Binding Class}" Margin="5"/>
            </StackPanel>
        </DataTemplate>
    </ui:ListView.ItemTemplate>
    <ui:ListView.GroupStyle>
        <GroupStyle>
            <GroupStyle.HeaderTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}" FontWeight="Bold" FontSize="16"/>
                </DataTemplate>
            </GroupStyle.HeaderTemplate>
        </GroupStyle>
    </ui:ListView.GroupStyle>
</ui:ListView>

GroupStyleGroupStyle.HeaderTemplate是用来自定义分组头部的显示方式。

GroupStyle: 这是一个用于定义分组样式的元素。它允许你为ui:ListView中的每个分组自定义外观和行为。在这个元素内部,你可以定义头部模板(HeaderTemplate)、容器样式(ContainerStyle)等。
GroupStyle.HeaderTemplate: 这个元素定义了分组头部的模板。通过这个模板,你可以自定义分组头部的外观。

实现的效果如下所示:

image-20240619122143726

基于IGrouping实现

在将数据分组时,我个人比较喜欢使用Linq的GroupBy。

相关cs代码如下:

  [ObservableProperty]
  private ObservableCollection<People> people;

  public IEnumerable<IGrouping<string?,People>> GroupedPeople { get; set; }

  public GroupDemoViewModel()
  {
      People = new ObservableCollection<People>
      {
          new People { Name = "小一", Class = "1班" },
          new People { Name = "小二", Class = "2班" },
          new People { Name = "王五", Class = "1班" },
          new People { Name = "小红", Class = "2班" },
          new People { Name = "小绿", Class = "1班" },
          new People { Name = "小刚", Class = "2班" },
      };

      GroupedPeople = People.GroupBy(x => x.Class);    
  }
 GroupedPeople = People.GroupBy(x => x.Class); 

这行代码使用LINQ的GroupBy方法对People集合进行分组。

GroupBy(x => x.Class)的作用是根据People对象的Class属性的值将这个集合分成多个组。每个组是一个包含有相同Class值的People对象集合。这里的x代表People集合中的每一个People对象,x => x.Class是一个lambda表达式,指定了分组的依据是People对象的Class属性。

GroupBy方法的结果是一个IEnumerable<IGrouping<string?, People>>类型的对象。IGrouping<string?, People>接口表示一个分组,其中string?是分组键的类型(在这个例子中是Class属性的类型),People是集合中元素的类型。每个IGrouping<string?, People>对象包含一个键(Key属性,即Class的值)和一个集合(包含所有具有该Class值的People对象)。

相关xaml代码如下:

 <ui:ListView ItemsSource="{Binding GroupedPeople}">
     <ui:ListView.ItemTemplate>
         <DataTemplate >
             <Expander Header="{Binding Key}">
                 <ui:ListView ItemsSource="{Binding}">
                     <ItemsControl.ItemTemplate>
                         <DataTemplate>
                             <StackPanel Orientation="Horizontal">
                                 <TextBlock Text="{Binding Name}" Margin="5"/>
                                 <TextBlock Text="{Binding Class}" Margin="5"/>
                             </StackPanel>
                         </DataTemplate>
                     </ItemsControl.ItemTemplate>
                 </ui:ListView>
             </Expander>
         </DataTemplate>
     </ui:ListView.ItemTemplate>
 </ui:ListView>

使用了Expander控件。

Expander是WPF中的一个控件,中文通常翻译为“扩展器”或“可折叠控件”。它是一个容器控件,允许用户通过点击标题栏来展开或折叠其内容区域。这种控件在用户界面设计中非常有用,可以用来隐藏或显示详细信息,从而节省屏幕空间。

实现效果如下所示:

image-20240619123207859

image-20240619123228203

回顾

本文介绍了遇到WPF对数据进行分组显示的需求时,可以选择的两种方案。一种方案基于ICollectionView,另一种方案基于IGrouping

基于ICollectionView的方案,在cs代码中通过CollectionViewSource.GetDefaultView方法获得集合的默认视图,创建一个PropertyGroupDescription类,ICollectionViewGroupDescriptions属性添加创建的PropertyGroupDescription对象。在xaml代码中,除了一般的数据绑定外,还添加了ListView.GroupStyle,设置了 GroupStyle.HeaderTemplate

基于IGrouping的方案,在cs代码中,使用LinqGroupBy方法对People集合进行分组。在xaml代码中在ListView的数据模板中使用Expander控件绑定分组的Key属性,在Expander控件中再包含一个ListView控件,绑定每个分组中的数据项。

标签:控件,Name,People,C#,分组,new,WPF,Class
From: https://www.cnblogs.com/mingupupu/p/18256035

相关文章

  • 如何快速实现MODBUS TCP转Profinet---泗博网关EPN-330
    泗博网关EPN-330可作为PROFINET从站,支持与西门子S7-200SMART/300/400/1200/1500全系列PLC以及具有PROFINET主站的系统无缝对接,而ModbusTCP端,可以与ModbusTCP从站设备、主站PLC、DCS系统以及组态软件等进行数据交互。通过EPN-330,可以快速实现MODBUSTCP转Profinet,轻松地将多个M......
  • 转型AI产品经理(12):“希克定律”如何应用在Chatbot产品中
    信息过载,这个对现代人来说是很常见的问题,信息获取变得越来越便捷的同时,也导致信息过载让我们无法及时做出有效决策,还可能演变成选择困难症。信息过载对用户体验的设计也有着显著的负面影响,如果我们的产品设计让人感觉太多信息,超出用户的认知承受力的话,会给产品带来以下负面的......
  • 转型AI产品经理(13):“峰终定律”如何应用在Chatbot产品中
    峰终定律是心理学中一个关于记忆形成的重要理论,该理论揭示了人们如何记忆过去的体验,特别是那些包含多个环节和情感变化的复杂体验,具体来说,人们在回顾一段体验时,记忆中最鲜明的部分是体验中的高峰和结束时的感受(无论是正面还是负面的)。换句话说,个体对整个体验的整体评价很大程......
  • UniformSpacingPanel Avalonia版本
    UniformSpacingPanel是HandyControl非常好用的一个容器,具备自动换行、等间距等特性,我一直用它来作为控制栏、属性编辑窗口的容器。刚看了下HandyControl官网甚至没有文档…UniformSpacingPanel真的是一个非常好用的容器,可以像StackPanel一样设置元素向某一个方向排列,并且......
  • 使用 curl 发送请求
    简介cURL是一个通过URL传输数据的,功能强大的命令行工具。cURL可以与ChromeDevtool工具配合使用,把浏览器发送的真实请求还原出来,附带认证信息,脱离浏览器执行,方便开发者重放请求、修改参数调试,编写脚本。也可以单独使用,根据自己的需求构造请求调整参数,构造多种接口测试场景......
  • mumu模拟器 adb shell 登录后执行命令 Inappropriate ioctl for device
    前言全局说明mumu模拟器adbshell登录后执行命令Inappropriateioctlfordevice一、说明二、问题执行任何命令,都提示:Inappropriateioctlfordevice三、解决方法方法一:执行过sudo或su重新登录方法二:退出,执行adbroot后再执行adbshell登录四、......
  • ZKSync空投惹争议来看Web3项目冷启动的困境?
    在Web3行业,Airdrop已经成为一种常见的用户吸引和项目冷启动方式,尤其是在Layer2赛道中。通过引导开发者和用户对潜在空投的预期,可以刺激他们积极参与生态系统。然而,最近ZKSync的空投结果引发了社区的广泛争论。背景:用户普遍期望ZKSync的空投会类似于其竞争对手Arbitrum和Optimism......
  • CPT111: PRINCIPLES OF PROGRAMMING
    CPT111:PRINCIPLESOFPROGRAMMINGSEMII2023/24ASSIGNMENT2DocumentCheckingApplication(DCAApp)Nowadays,thankstotheInternet,peoplehavemanyopportunitiestostudyanytimeandanywhere,witheasieraccesstoanabundanceofinformationwithout......
  • 【CMake】target属性
    1、INCLUDE_DIRECTORIES头文件搜索目录列表。除了可以使用target_include_directories命令修改头文件搜索目录以外,还可以直接使用set_property命令修改target的头文件搜索目录。target的INCLUDE_DIRECTORIES属性会使用目录的INCLUDE_DIRECTORIES属性初始化。可以使用include_di......
  • ADO.NET ExecuteScalar 方法的使用及注意
    ExecuteScalar方法允许我们查询单一结果,我们来看看什么是单一结果,有那些需要注意的事项1.下面是我对 ExecuteScalar的简单封装,接下来我们看看,如何使用///<summary>///查询单一结果///</summary>///<paramname="sql"></param>///<paramname="pars"></param>......