WPF应用实战开发指南 - 如何实现DataGrid分组显示及嵌套明细展示效果

在之前一些文章中介绍了Winform程序中对表格内容进行了分组的展示,在WPF应用中同样也可以对表格的内容进行分组展示,不过处理方式和Winform有所差异,本文同样基于SqlSugar开发框架的基础上,实现在WPF应用中实现DataGrid的分组显示,以及嵌套明细展示效果。

PS:给大家推荐一个C#开发可以用到的界面组件——DevExpress WPF,它拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。

点击获取DevExpress v23.2正式版(Q技术交流:532598169)

回顾Winform的表格分组展示效果

对于常规的二维表格数据,如下所示。

WPF应用实战开发指南 - 如何实现DataGrid分组显示及嵌套明细展示效果

我们根据其中一个字段对表格数据进行分组展示,这样更方便用户对特定数据的归类展示处理。

WPF应用实战开发指南 - 如何实现DataGrid分组显示及嵌套明细展示效果

Winform的界面中,我们基于DevExpress 的GridView控件对数据进行分组展示,其中代码如下所示。

//增加汇总字段和显示
var gridView1 = this.winGridViewPager1.gridView1;
if (checkGroup.Checked)
{
this.winGridViewPager1.ShowLineNumber = false;
gridView1.IndicatorWidth = 0;
gridView1.OptionsView.ShowGroupExpandCollapseButtons = true;//显示折叠的分组
gridView1.OptionsView.AllowCellMerge = true; //允许合并字段
gridView1.OptionsView.GroupDrawMode = GroupDrawMode.Standard;

gridView1.GroupSummary.Clear();
gridView1.Columns["Category"].GroupIndex = 0;//对类别进行分组展示

var item = new GridGroupSummaryItem();
item.FieldName = "Id";
item.DisplayFormat = " (合计数量 = {0:n})";
item.SummaryType = DevExpress.Data.SummaryItemType.Count;//Sum、Average等
gridView1.GroupSummary.Add(item);
gridView1.ExpandAllGroups();
}
else
{
gridView1.GroupSummary.Clear();
this.winGridViewPager1.ShowLineNumber = true;
gridView1.OptionsView.AllowCellMerge = false;
}

我们可以看到,只需要实现对 GroupSummary的添加处理即可实现汇总效果的展示。

在WPF应用中实现DataGrid的分组显示

在WPF应用中,数据的显示通过DataGrid控件进行展示,默认是没有分组效果的,如果需要分组效果,需要定制表格的分组样式才能达到效果。

同样基于SqlSugar开发框架的基础上,基于原料表的数据展示,实现在WPF应用中实现DataGrid的分组显示,实现的效果如下所示。

WPF应用实战开发指南 - 如何实现DataGrid分组显示及嵌套明细展示效果

我们这里根据【类别】字段来进行分组统一,其中分组样式在XAML上定义如下所示。

<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock FontWeight="Bold" Text="类别:" />
<TextBlock FontWeight="Bold" Text="{Binding Name}" />
<TextBlock Text="{Binding ItemCount, StringFormat=' (合计数量 = {0} )'}" />
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock FontWeight="Bold" Text="{Binding Name}" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</DataGrid.GroupStyle>

如果我们需要控件的虚拟化处理(提高显示性能),那么设置下虚拟化处理属性即可。<DataGrid

x:Name="grid"
Grid.Row="1"
hc:DataGridAttach.ShowRowNumber="True"
AutoGenerateColumns="False"
HeadersVisibility="All"
IsReadOnly="True"
ItemsSource="{Binding ViewModel.Items}"
MouseDoubleClick="DataGrid_MouseDoubleClick"
RowHeaderWidth="60"
SelectionChanged="DataGrid_SelectionChanged"
SelectionMode="Extended"
VerticalScrollBarVisibility="Auto"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.IsVirtualizingWhenGrouping="True"
>

表格的字段,如没有特殊处理,我们用常用的定义效果即可,如下所示。

<DataGrid.Columns>
<DataGridTextColumn
Width="SizeToCells"
MinWidth="100"
Binding="{Binding Id}"
Header="ID编号" />
<DataGridTextColumn
Width="SizeToCells"
MinWidth="100"
Binding="{Binding Category}"
Header="类别" />
<DataGridTextColumn
Width="SizeToCells"
MinWidth="100"
Binding="{Binding Code}"
Header="原料编码" />
..............
</DataGrid.Columns>

对于分组的效果处理,我们后台的C#代码也需要进行一定的适应处理,如下所示。

我们采用MVVM的模式处理查询操作,获得数据并转换为CollectionView后,设置分组信息即可,如下代码所示。

/// <summary>
/// 查询处理
/// </summary>
[RelayCommand]
private async Task Search()
{
//查询获得视图模型的数据
await this.ViewModel.SearchCommand.ExecuteAsync(null);

//把数据集合转换为CollectionView,并设置其GroupDescriptions
var viewSource = CollectionViewSource.GetDefaultView(this.ViewModel.Items);
if (this.ViewModel.IsUseGroup)
{
viewSource.GroupDescriptions.Clear();
viewSource.GroupDescriptions.Add(new PropertyGroupDescription("Category"));
}
this.grid.ItemsSource = viewSource;
}

这样就是写了数据的显示和分组处理了。

上面的SearchCommand就是视图模型基类函数的查询获得数据的处理方式。

/// <summary>
/// 触发查询处理命令
/// </summary>
/// <returns></returns>
[RelayCommand]
public virtual async Task Search()
{
//切换第一页
this.PagerInfo.CurrentPageIndex = 1;
//查询更新
await GetData();
}

GetData也是视图模型基类函数的通用处理方式,通过分页和条件信息,获得对应的数据记录。

/// <summary>
/// 根据分页和查询条件查询,请求数据
/// </summary>
/// <returns></returns>
public virtual async Task GetData()
{
//转换下分页信息
ConvertPagingInfo();
var result = await service.GetListAsync(this.PageDto);
if (result != null)
{
this.Items = result.Items?.ToList();
this.PagerInfo.RecordCount = result.TotalCount;
}
}
在WPF应用中实现嵌套明细展示效果

我们这里继续介绍另外一个DataGrid的效果,通过明细展示的方式显示其中一条记录相关联的表格信息,有时候也可以看成是主从关联信息。

单我们单击其中一条记录的时候,展示嵌套表格,展示详细的明细信息,如下效果所示。

WPF应用实战开发指南 - 如何实现DataGrid分组显示及嵌套明细展示效果

这个效果主要是通过定义DataGrid.RowDetailsTemplate进行明细内容的处理的。例如我们定义明细的模板如下所示,其实也就是显示另外一个表格信息。

<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid
MaxHeight="500"
hc:DataGridAttach.ShowRowNumber="True"
AlternatingRowBackground="LightBlue"
AutoGenerateColumns="False"
HeadersVisibility="Column"
IsReadOnly="True"
RowHeaderWidth="60"
ScrollViewer.VerticalScrollBarVisibility="Auto"
SelectionUnit="FullRow">
<DataGrid.Columns>
<DataGridTextColumn
MinWidth="120"
Binding="{Binding Name}"
Header="显示名称" />
<DataGridTemplateColumn Width="80" Header="图标">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ui:SymbolIcon
Width="32"
FontSize="32"
Symbol="{Binding Icon}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn
Width="80"
Binding="{Binding Seq}"
Header="排序" />
<DataGridTextColumn
Width="100"
Binding="{Binding FunctionId}"
Header="功能ID" />
</DataGrid.Columns>

</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>

Xaml的结构如下所示。

WPF应用实战开发指南 - 如何实现DataGrid分组显示及嵌套明细展示效果

另外,我们在视图模型中除了定义一级的数据记录外,还定义一个嵌套记录集合对象,如下所示。

/// <summary>
/// 编辑的数据列表
/// </summary>
[ObservableProperty]
private ObservableCollection<MenuInfo>? menuItems;

/// <summary>
/// 指定父级的子级数据列表
/// </summary>
[ObservableProperty]
private ObservableCollection<MenuInfo>? detailItems;

这样我们在行选择变化的时候,重新获得明细的记录,然后绑定显示事件即可,如下代码所示。

/// <summary>
/// 记录行变化的时候,触发明细记录的获取处理
/// </summary>
private async void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var datagrid = sender as DataGrid;
if (datagrid != null)
{
var item = datagrid!.SelectedItem as MenuInfo;
if (item != null)
{
await ViewModel.GetDetailList(item.Id);
}
}
}

而在页面初始化的时候,我们可以构造一个事件,用来绑定明细记录的绑定显示处理。

//明细记录可见性变化的时候,触发数据的绑定处理事件
this.grid.RowDetailsVisibilityChanged += (s, e) =>
{
var datagrid = s as DataGrid;
if (datagrid != null)
{
var DetailsDataGrid = e.DetailsElement as DataGrid;
if(DetailsDataGrid != null)
{
DetailsDataGrid.ItemsSource = viewModel.DetailItems;
}
}
};

这样就可以正常的显示嵌套明细的记录了。

本文转载自:博客园 - 伍华聪

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WPF Prism是微软新一代的界面开发框架,它具有丰富的功能和灵活的架构,广泛应用于桌面应用程序和Web应用程序的开发中。朝夕停车场项目是基于WPF Prism框架的一个实战项目,它实现了停车场的智能化管理,包括车辆进入和出场的自动识别,车位的实时监测和调度,以及财务管理和数据分析等功能。 该项目的源码包含了多个模块和组件,采用了MVVM架构和依赖注入技术,使代码组织和维护非常方便。项目中的主要模块包括: 1. Shell模块:该模块是整个应用程序的容器,它提供了主窗口和导航栏等界面组件,以及对其他模块的管理和协调。 2. Home模块:该模块实现了停车场的实时监控和调度功能,包括车位的占用和空闲状态显示,车辆进出场的记录和管理,以及停车位的预定和预约等功能。 3. Financial模块:该模块实现了停车场的财务管理和数据分析功能,包括车位租赁、停车费用计算和缴纳,以及停车场运营数据的统计和分析等功能。 4. Configuration模块:该模块实现了停车场的基础配置和参数管理功能,包括车位数量、收费标准和系统设置等功能。 5. Common模块:该模块包含了一些公共的模型和工具类,用于提供系统级别的服务和支持。 通过这个实战项目的源码学习,可以深入了解WPF Prism框架的应用及其MVVM架构和依赖注入的设计思想,也可以了解如何实现一个完整的智能化停车场管理系统。同时,该项目源码可以作为一个参考,通过在此基础上进行二次开发和定制,实现更加具体化的应用需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值