前言

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

WPF/C#:显示分组数据的两种方式的更多相关文章

  1. WPF内嵌网页的两种方式

    在wpf程序中,有时会内嵌网页.内嵌网页有两种方法,一种是使用wpf自带WebBrowser控件来调用IE内核,另一种是使用CefSharp包来调用chrom内核. 一.第一种使用自带WebBrows ...

  2. WPF TextBlock 文本换行的两种方式

    第一种: <TextBlock> This is line 1.<LineBreak/> This is line 2. </TextBlock> 第二种 < ...

  3. Android中EditText显示明文与密文的两种方式

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 记录输入框显示.隐藏密码的简单布局以及实现方式. 效果图    代码分析 方式一 /**方式一:*/ private void sh ...

  4. Android中EditText显示明文与密码的两种方式

    效果图如下所述: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:and ...

  5. C#实现接口的两种方式:显示实现和隐式实现接口

    本示例声明一个接口IDimensions 和一个类 Box,显式实现了接口成员 GetLength 和 GetWidth. 通过接口实例 dimensions 访问这些成员. interface ID ...

  6. 【Python】Python figure显示的两种方式

    1. 两种方式: 终端输出图像新窗口输出图像 2. 终端输出命令: %matplotlib inline 新窗口输出命令: %matplotlib qt5 注意此两个语句是命令行输入,若在spyder ...

  7. CSharpGL(18)分别处理glDrawArrays()和glDrawElements()两种方式下的拾取(ColorCodedPicking)

    CSharpGL(18)分别处理glDrawArrays()和glDrawElements()两种方式下的拾取(ColorCodedPicking) 我在(Modern OpenGL用Shader拾取 ...

  8. 在基于MVC的Web项目中使用Web API和直接连接两种方式混合式接入

    在我之前介绍的混合式开发框架中,其界面是基于Winform的实现方式,后台使用Web API.WCF服务以及直接连接数据库的几种方式混合式接入,在Web项目中我们也可以采用这种方式实现混合式的接入方式 ...

  9. Xamarin Android Activity全屏的两种方式

    方式一 直接在Activity的Attribute中定义 如下 在 MainActivity 中 [Activity(Label = "app", MainLauncher = t ...

  10. placeholder实现的两种方式

    /** * PlaceHolder组件 * $(input).placeholder({ * word: // @string 提示文本 * color: // @string 文本颜色 * evtT ...

随机推荐

  1. IDC报告:阿里云领跑中国数据库市场年度份额首超传统厂商

    ​ 简介: IDC报告显示,2020年中国关系型数据库软件市场规模达到121.8亿元,同比增长36.5%.其中,以公有云模式部署的关系型数据库市场占比达到51.5%,首次超过传统线下部署模式市场规模, ...

  2. 2019-4-12-VisualStudio-好用插件集合

    title author date CreateTime categories VisualStudio 好用插件集合 lindexi 2019-04-12 09:37:47 +0800 2019-0 ...

  3. 基于权电阻网络的VGA色条显示#DE10-lite#verilog#qp

  4. 自制一个发送验证码的10秒倒计时js效果

    <template>     <div class="conten1">         <input class="code"  ...

  5. Codeforces Round 940 (Div. 2) and CodeCraft-23 (A-E)

    A. Stickogon 题意:给定 \(n\) 根木棒长度,问最多构成几个多边形. 贪心,四边形不会优于三角形. submission B. A BIT of a Construction 题意:构 ...

  6. PHP游戏线下线上陪玩平台APP小程序H5源码开发多少钱?可用于家政,陪诊,陪伴服务等

    做陪玩app项目,不少创业者们都比较头疼该如何去选择软件系统!目前软件市场上,陪玩app平台的软件系统五花八门,价位也是参差不齐.创业者们都比较纠结是定制开发,还是选择开元源码二次开 发? 前两天成都 ...

  7. 联想G470安装黑苹果

    macos10136 黑苹果usb无线网卡 1.系统下载: 下面是我自制的带clover 4596版本的u盘镜像: 链接: https://pan.baidu.com/s/1wRdVddwkei7bf ...

  8. pdo类

    testmysql.php <?php require_once "./mypdo.php"; //do something... //查一行 $id = 3; //$sql ...

  9. WEB服务与NGINX(11)-NGINX状态页

    nginx状态页 nginx的状态页功能用于输出nginx的基本状态信息,基于ngx_http_stub_status_module模块实现. 默认情况下不生成此模块,应使用--with-http_s ...

  10. shape-outside

    shape-outside定义一个由内容区域的外边缘封闭形成的形状 shape-outside 是一个非常实用的属性,可以实现一些比较复杂的文本环绕效果. shape-outside 的兼容性比较好, ...