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

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

前言

本文介绍自己在遇到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: 这个元素定义了分组头部的模板。通过这个模板,你可以自定义分组头部的外观。

实现的效果如下所示:

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

实现效果如下所示:

回顾

本文介绍了遇到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控件,绑定每个分组中的数据项。

目录
相关文章
|
12天前
|
C#
C# WPF 中 外部图标引入iconfont,无法正常显示问题 【小白记录】
本文介绍了在C# WPF应用程序中引入外部iconfont图标时可能遇到的显示问题及其解决方法:1) 检查资源路径和引入格式是否正确,确保字体文件引用格式为“#xxxx”,并正确指向字体文件位置;2) 确保图标资源被包含在程序集中,通过设置字体文件的生成操作为Resource(资源)来实现。
C# WPF 中 外部图标引入iconfont,无法正常显示问题 【小白记录】
|
19天前
|
编解码 C# 数据库
C# + WPF 音频播放器 界面优雅,体验良好
【9月更文挑战第18天】这是一个用 C# 和 WPF 实现的音频播放器示例,界面简洁美观,功能丰富。设计包括播放/暂停按钮、进度条、音量控制滑块、歌曲列表和专辑封面显示。功能实现涵盖音频播放、进度条控制、音量调节及歌曲列表管理。通过响应式设计、动画效果、快捷键支持和错误处理,提升用户体验。可根据需求扩展更多功能。
|
27天前
|
存储 C# 开发者
枚举与结构体的应用:C#中的数据组织艺术
在C#编程中,枚举(`enum`)和结构体(`struct`)是非常重要的数据类型。枚举用于定义命名常量集合,提高代码可读性;结构体则封装相关数据字段,适合小型数据集。本文从基本概念入手,探讨它们的使用技巧、常见问题及解决方案,帮助开发者更好地利用这些特性构建健壮的应用程序。
25 8
|
2月前
|
传感器 C# 监控
硬件交互新体验:WPF与传感器的完美结合——从初始化串行端口到读取温度数据,一步步教你打造实时监控的智能应用
【8月更文挑战第31天】本文通过详细教程,指导Windows Presentation Foundation (WPF) 开发者如何读取并处理温度传感器数据,增强应用程序的功能性和用户体验。首先,通过`.NET Framework`的`Serial Port`类实现与传感器的串行通信;接着,创建WPF界面显示实时数据;最后,提供示例代码说明如何初始化串行端口及读取数据。无论哪种传感器,只要支持串行通信,均可采用类似方法集成到WPF应用中。适合希望掌握硬件交互技术的WPF开发者参考。
43 0
|
2月前
|
数据处理 开发者 C#
WPF数据绑定实战:从零开始,带你玩转数据与界面同步,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,数据绑定是核心技能之一,它能实现界面元素与数据源的同步更新。本文详细介绍了WPF数据绑定的概念与实现方法,包括属性绑定、元素绑定及路径绑定等技术,并通过示例代码展示了如何创建数据绑定。通过数据绑定,开发者不仅能简化代码、提高可维护性,还能提升用户体验。无论初学者还是有经验的开发者,都能从中受益,更好地掌握WPF数据绑定技巧。
36 0
|
2月前
|
C#
C# WPF 将第三方DLL嵌入 exe
C# WPF 将第三方DLL嵌入 exe
36 0
|
2月前
|
前端开发 C# 容器
WPF/C#:实现导航功能
WPF/C#:实现导航功能
44 0
|
2月前
|
设计模式 测试技术 C#
WPF/C#:在WPF中如何实现依赖注入
WPF/C#:在WPF中如何实现依赖注入
45 0
|
2月前
|
前端开发 C# Windows
WPF/C#:如何实现拖拉元素
WPF/C#:如何实现拖拉元素
44 0
|
2月前
|
存储 C# 索引
WPF/C#:BusinessLayerValidation
WPF/C#:BusinessLayerValidation
30 0