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

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

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

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

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 = newGridGroupSummaryItem();
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的添加处理即可实现汇总效果的展示。

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

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

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

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

<DataGrid.GroupStyle>
    <GroupStyle>
        <GroupStyle.ContainerStyle>
            <StyleTargetType="{x:Type GroupItem}">
                <SetterProperty="Template">
                    <Setter.Value>
                        <ControlTemplateTargetType="{x:Type GroupItem}">
                            <ExpanderIsExpanded="True">
                                <Expander.Header>
                                    <StackPanelOrientation="Horizontal">
                                        <TextBlockFontWeight="Bold"Text="类别:" />
                                        <TextBlockFontWeight="Bold"Text="{Binding Name}" />
                                        <TextBlockText="{Binding ItemCount, StringFormat='    (合计数量 = {0} )'}" />
                                    </StackPanel>
                                </Expander.Header>
                                <ItemsPresenter/>
                            </Expander>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </GroupStyle.ContainerStyle>
        <GroupStyle.HeaderTemplate>
            <DataTemplate>
                <TextBlockFontWeight="Bold"Text="{Binding Name}" />
            </DataTemplate>
        </GroupStyle.HeaderTemplate>
    </GroupStyle>
</DataGrid.GroupStyle>

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

<DataGridx: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>
    <DataGridTextColumnWidth="SizeToCells"MinWidth="100"Binding="{Binding Id}"Header="ID编号" />
    <DataGridTextColumnWidth="SizeToCells"MinWidth="100"Binding="{Binding Category}"Header="类别" />
    <DataGridTextColumnWidth="SizeToCells"MinWidth="100"Binding="{Binding Code}"Header="原料编码" />..............</DataGrid.Columns>

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

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

/// <summary>
///查询处理/// </summary>
[RelayCommand]private asyncTask 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 asyncTask Search()
{
//切换第一页 this.PagerInfo.CurrentPageIndex = 1;//查询更新 awaitGetData();
}

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

    /// <summary>
    ///根据分页和查询条件查询,请求数据/// </summary>
    /// <returns></returns>
    public virtual asyncTask GetData()
{
//转换下分页信息 ConvertPagingInfo();var result = await service.GetListAsync(this.PageDto);if (result != null)
{
this.Items = result.Items?.ToList();this.PagerInfo.RecordCount =result.TotalCount;
}
}

3、在WPF应用中实现嵌套明细展示效果

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

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

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

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

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

Xaml的结构如下所示。

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

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

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

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

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

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

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

标签: none

添加新评论