WPF/C#:如何将数据分组显示
WPF Samples中的示例
在WPF Samples中有一个关于Grouping的Demo。
该Demo结构如下:

MainWindow.xaml如下:
<Window x:Class="Grouping.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:local="clr-namespace:Grouping"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" SizeToContent="Height">
<StackPanel>
<StackPanel.Resources>
<XmlDataProvider x:Key="MyTasks" XPath="Tasks/Task">
<x:XData>
<Tasks xmlns="">
<Task Name="Groceries" Priority="2" Type="Home">
<Description>Pick up Groceries and Detergent</Description>
</Task>
<Task Name="Laundry" Priority="2" Type="Home">
<Description>Do Laundry</Description>
</Task>
<Task Name="Email" Priority="1" Type="Work">
<Description>Email Clients</Description>
</Task>
<Task Name="Clean" Priority="3" Type="Work">
<Description>Clean my office</Description>
</Task>
<Task Name="Dinner" Priority="1" Type="Home">
<Description>Get ready for family reunion</Description>
</Task>
<Task Name="Proposals" Priority="2" Type="Work">
<Description>Review new budget proposals</Description>
</Task>
</Tasks>
</x:XData>
</XmlDataProvider>
</StackPanel.Resources>
<TextBlock Margin="12,5,5,0" FontSize="20" Text="My Task List"/>
<CheckBox Margin="10,5,5,10" Checked="AddGrouping"
Unchecked="RemoveGrouping">Group by task type</CheckBox>
<ItemsControl Margin="10" Name="myItemsControl"
ItemsSource="{Binding Source={StaticResource MyTasks}}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="18"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
</DataTemplate.Resources>
<Grid>
<Ellipse Fill="Silver"/>
<StackPanel>
<TextBlock Margin="3,3,3,0"
Text="{Binding XPath=@Name}"/>
<TextBlock Margin="3,0,3,7"
Text="{Binding XPath=@Priority}"/>
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Control.Width" Value="100"/>
<Setter Property="Control.Margin" Value="5"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock FontWeight="Bold" FontSize="15"
Text="{Binding Path=Name}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ItemsControl.GroupStyle>
</ItemsControl>
</StackPanel>
</Window>
其中:
<StackPanel.Resources>
<XmlDataProvider x:Key="MyTasks" XPath="Tasks/Task">
<x:XData>
<Tasks xmlns="">
<Task Name="Groceries" Priority="2" Type="Home">
<Description>Pick up Groceries and Detergent</Description>
</Task>
<Task Name="Laundry" Priority="2" Type="Home">
<Description>Do Laundry</Description>
</Task>
<Task Name="Email" Priority="1" Type="Work">
<Description>Email Clients</Description>
</Task>
<Task Name="Clean" Priority="3" Type="Work">
<Description>Clean my office</Description>
</Task>
<Task Name="Dinner" Priority="1" Type="Home">
<Description>Get ready for family reunion</Description>
</Task>
<Task Name="Proposals" Priority="2" Type="Work">
<Description>Review new budget proposals</Description>
</Task>
</Tasks>
</x:XData>
</XmlDataProvider>
</StackPanel.Resources>
使用XmlDataProvider来加载和绑定XML数据。
<ItemsControl Margin="10" Name="myItemsControl"
ItemsSource="{Binding Source={StaticResource MyTasks}}">
将MyTasks绑定到ItemsControl。
<DataTemplate>
<DataTemplate.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="18"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
</DataTemplate.Resources>
<Grid>
<Ellipse Fill="Silver"/>
<StackPanel>
<TextBlock Margin="3,3,3,0"
Text="{Binding XPath=@Name}"/>
<TextBlock Margin="3,0,3,7"
Text="{Binding XPath=@Priority}"/>
</StackPanel>
</Grid>
</DataTemplate>
设置数据模板。
跟本次介绍的主题Grouping有关的内容如下:
<ItemsControl.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock FontWeight="Bold" FontSize="15"
Text="{Binding Path=Name}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ItemsControl.GroupStyle>

ItemsControl.GroupStyle获取定义每个级别的组的外观的 GroupStyle 对象集合。
GroupStyle如下所示:
public class GroupStyle : INotifyPropertyChanged
{
public static readonly ItemsPanelTemplate DefaultGroupPanel;
public GroupStyle();
public static GroupStyle Default { get; }
[DefaultValue(0)]
public int AlternationCount { get; set; }
[DefaultValue(null)]
public Style ContainerStyle { get; set; }
[DefaultValue(null)]
public StyleSelector ContainerStyleSelector { get; set; }
[DefaultValue(null)]
public string HeaderStringFormat { get; set; }
[DefaultValue(null)]
public DataTemplate HeaderTemplate { get; set; }
[DefaultValue(null)]
public DataTemplateSelector HeaderTemplateSelector { get; set; }
[DefaultValue(false)]
public bool HidesIfEmpty { get; set; }
public ItemsPanelTemplate Panel { get; set; }
protected event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e);
}
}
这里设置了GroupStyle.HeaderTemplate,这个元素定义了分组头的数据模板。数据模板决定了分组头的具体显示方式。
<TextBlock FontWeight="Bold" FontSize="15"
Text="{Binding Path=Name}"/>
这里的Name指的是CollectionViewGroup 类的Name属性。

CollectionViewGroup 类表示根据 GroupDescriptions 由 CollectionView 对象创建的组。
MainWindow.cs如下:
public partial class MainWindow : Window
{
private CollectionView _myView;
public MainWindow()
{
InitializeComponent();
}
private void AddGrouping(object sender, RoutedEventArgs e)
{
_myView = (CollectionView) CollectionViewSource.GetDefaultView(myItemsControl.ItemsSource);
if (_myView.CanGroup)
{
var groupDescription
= new PropertyGroupDescription("@Type");
_myView.GroupDescriptions.Add(groupDescription);
}
}
private void RemoveGrouping(object sender, RoutedEventArgs e)
{
_myView = (CollectionView) CollectionViewSource.GetDefaultView(myItemsControl.ItemsSource);
_myView.GroupDescriptions.Clear();
}
}
只包含两个事件处理程序。
进行分组是这样写的:
private void AddGrouping(object sender, RoutedEventArgs e)
{
_myView = (CollectionView) CollectionViewSource.GetDefaultView(myItemsControl.ItemsSource);
if (_myView.CanGroup)
{
var groupDescription
= new PropertyGroupDescription("@Type");
_myView.GroupDescriptions.Add(groupDescription);
}
}
_myView = (CollectionView) CollectionViewSource.GetDefaultView(myItemsControl.ItemsSource);
虽然CollectionViewSource本身不是一个静态类,但它提供了一个静态方法GetDefaultView,这个方法用于获取与特定数据源关联的默认视图。这种设计允许开发者不必实例化CollectionViewSource对象就能访问和操作数据源的视图。

var groupDescription
= new PropertyGroupDescription("@Type");
_myView.GroupDescriptions.Add(groupDescription);

PropertyGroupDescription类描述使用属性名作为条件对项进行分组。
使用的是这个构造函数:

= new PropertyGroupDescription("@Type");
在XML和XPath的上下文中,@符号用于引用元素的属性。
这样就实现了基于Type属性进行分组。
private void RemoveGrouping(object sender, RoutedEventArgs e)
{
_myView = (CollectionView) CollectionViewSource.GetDefaultView(myItemsControl.ItemsSource);
_myView.GroupDescriptions.Clear();
}
取消分组将_myView.GroupDescriptions清空即可。
该Demo的效果如下:

分组前:

分组后:

代码来源
[WPF-Samples/Data Binding/Grouping at main · microsoft/WPF-Samples (github.com)]
欢迎关注微信公众号:DotNet学习交流。
WPF/C#:如何将数据分组显示的更多相关文章
- wpf CollectionViewSource与ListBox的折叠、分组显示,及输入关键字 Filter的筛选
在wpf中虽然ObservableCollection<T>作为ListBox的Itemsource,很好,很强大!但是CollectionViewSource与ListBox才是天作之合 ...
- ember.js:使用笔记4 数组数据的分组显示
除了之前介绍的将数组数据在一个页面中输出的方法,还可以将数组数据分组,按照点击,在不同页面中分别显示,方法为: Model: 例如:Table Router: 设置一个父对象和子对象设置: this. ...
- MySQL数据中分级分组显示数据
前面已经有了SqlServer数据分级分组显示数据了.今天又来做一个MySQL数据库中的分级分组显示,SqlServer中用到了递归,这里为了简单就直接把根的数据显示为0 ,而不用递归了. 在MySQ ...
- PHP.37-TP框架商城应用实例-后台13-商品管理-扩展分类的添加、显示【数据分组】、搜索分类【多对多】
商品扩展分类 需求:一件商品能有多个扩展分类,搜索任何一个分类都能搜出该商品 建表[扩展分类表] drop table if exists p39_goods_cat; create table p3 ...
- 小程序开发笔记(八)—Js数组按日期分组显示数据
数据分组展示有两种方式,一种是后端直接传入分组格式的Json数据,另一种是我们在前端自己转换格式,这里我们在前端处理转换按日期分组的数据格式 1.例如后端返回数据格式为: [{createtime:' ...
- MySQL:基础—数据分组
MySQL:基础-数据分组 1.为什么要分组: 比如一个表中有多条订单记录,如上图,每条记录对应着一个商品,现在我要查询 每个商品被订购的单数 准备出货?也就是找到每个商品被订购的数量. 如果只找一个 ...
- Linq DataTable Group By 分组显示人员明细
实现功能: 多个字段分组源码样例: 原始数据: 分组后的输出结果: 源代码: public static void PrintPersons() { //准备数据 DataTable dt ...
- wpf采用Xps实现文档显示、套打功能(原创)
近期的一个项目需对数据进行套打,用户要求现场不允许安装office.页面预览显示必须要与文档完全一致,xps文档来对数据进行处理.Wpf的DocumentView 控件可以直接将数据进行显示,xps也 ...
- 重新想象 Windows 8 Store Apps (12) - 控件之 GridView 特性: 拖动项, 项尺寸可变, 分组显示
原文:重新想象 Windows 8 Store Apps (12) - 控件之 GridView 特性: 拖动项, 项尺寸可变, 分组显示 [源码下载] 重新想象 Windows 8 Store Ap ...
- 背水一战 Windows 10 (51) - 控件(集合类): ItemsControl - 项模板选择器, 数据分组
[源码下载] 背水一战 Windows 10 (51) - 控件(集合类): ItemsControl - 项模板选择器, 数据分组 作者:webabcd 介绍背水一战 Windows 10 之 控件 ...
随机推荐
- 庖丁解牛-图解MySQL 8.0优化器查询解析篇
简介: SQL优化器本质上是一种高度抽象化的数据接口的实现,经过该设计,客户可以使用更通用且易于理解的SQL语言,对数据进行操作和处理,而不需要关注和抽象自己的数据接口,极大地解放了客户的应用程序. ...
- 7.deployment扩容-查看pod使用的CPU-统计ready状态节点数量
官方文档:https://kubernetes.io/zh-cn/docs/tasks/run-application/scale-stateful-set/题目1: 将名为loadbalancer的 ...
- 九、ODBC External Table Of Doris
ODBC External Table Of Doris 提供了Doris通过数据库访问的标准接口(ODBC)来访问外部表 ODBC Driver的安装和配置: 要求所有的BE节点都安装上相同的Dri ...
- 【YoloDeployCsharp】基于.NET Framework的YOLO深度学习模型部署测试平台
1. 项目介绍 基于.NET Framework 4.8 开发的深度学习模型部署测试平台,提供了YOLO框架的主流系列模型,包括YOLOv8~v9,以及其系列下的Det.Seg.Pose.Obb ...
- FFmpeg开发笔记(十九)FFmpeg开启两个线程分别解码音视频
同步播放音视频的时候,<FFmpeg开发实战:从零基础到短视频上线>一书第10章的示例程序playsync.c采取一边遍历一边播放的方式,在源文件的音频流和视频流交错读取的情况下,该方式 ...
- 如何实现surging 多语言混合微服务异构
1. 背景 作为微服务体系, 应该是不限语言的, 不管是.net.java, 都可以是一个微服务. 可以使用JAVA或者.NET 去实现业务模块,通过统一的消息模型进行传输调用因客户技术栈以多语言,多 ...
- kibana-6.2.4-amd64的安装
ubuntu系统 kibana: https://mirrors.huaweicloud.com/kibana/?C=N&O=D 找到6.2.4的下载连接 方法一: 下载tar包,解压即可: ...
- LVS负载均衡(4)-- LVS FWM防火墙标记
防火墙标记的作用是:借助于防火墙标记来分类报文,然后基于标记定义集群服务:可将多个不同的应用使用同一个集群服务进行调度. 实现方法: 在Director主机打标记,作用在mangle表的PREROUT ...
- three.js教程4-Group层级模型
1.组对象Group.层级模型-形成树状结构 //创建两个网格模型mesh1.mesh2 const geometry = new THREE.BoxGeometry(20, 20, 20); con ...
- PasteSpider之appsettings.json中的Serilog的配置,分流不同日志层级的信息!
在实际使用Serilog中,我们通常会有不一样的需求,常见的比如 1.按照等级,高级哪个等级的才记录 2.记录文件每个多大,超过的划分到下一个文件中 3.不同等级的记录到不同的位置中 4.按照不一样的 ...