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 之 控件 ...
随机推荐
- 阿里千万实例可观测采集器-iLogtail正式开源
简介:11月23日,阿里正式开源可观测数据采集器iLogtail.作为阿里内部可观测数据采集的基础设施,iLogtail承载了阿里巴巴集团.蚂蚁的日志.监控.Trace.事件等多种可观测数据的采集工 ...
- Apache Hudi 在 B 站构建实时数据湖的实践
简介: B 站选择 Flink + Hudi 的数据湖技术方案,以及针对其做出的优化. 本文作者喻兆靖,介绍了为什么 B 站选择 Flink + Hudi 的数据湖技术方案,以及针对其做出的优化.主 ...
- [FAQ] 为什么部署到 github pages 时自定义域名总失效 (push-dir)
Github_Pages 能方便我们部署静态页面,并且还支持 CNAME 自定义域名. $ yarn add --dev push-dir $ xxx build $ push-dir --dir=d ...
- 学习 Avalonia 框架笔记 如何创建一个全屏置顶的 X11 应用窗口
本文记录我从 Avalonia 框架里面学到如何创建一个全屏置顶的 X11 应用窗口的方法 开始之前,先从 Avalonia 或 CPF 里面拷贝足够的代码,这部分代码可以从本文末尾找到下载方法 设置 ...
- 9.prometheus监控--监控springboot2.x(Java)
一.环境部署 yum search java | grep jdk yum install -y java-11-openjdk-devel 二.监控java应用(tomcat/jar) JMX ex ...
- 四:海思Hi3516CV500/Hi3516DV300
Hi3516CV500 和 Hi3516DV300 均是海思推出的 IP Camera SoC [System-on-a-Chip:SoC芯片是一种集成电路的芯片] 芯片. 针对海思 HI3516D ...
- vuepress搭建
参考文章 中国 NPM 镜像 https://npmmirror.com/ 资料 链接:https://pan.baidu.com/s/1O1WitowUR4iwbrdsG92Gew 提取码:adj4 ...
- Typora最后的免费版本0.11.18
Typora最后的免费版本为0.11.18. 之后的1.x开始收费. 免费版本0.11.18的百度网盘链接如下(永久链接): 链接:https://pan.baidu.com/s/1XizAD0SFp ...
- Vue的Vue-ls使用
Vue插件,用于从Vue上下文中使用本地Storage,会话Storage和内存Storage 1. 安装 NPM npm install vue-ls --save YARN yarn add vu ...
- flask3之CBV和session
flask的CBV CBV书写案例 from flask import Flask app=Flask(__name__) #FBA @app.route("/") def ind ...