You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF C#:如何为分组DataGrid添加自定义表头(含无Card记录数统计)

在WPF C#中为分组DataGrid添加带统计的自定义表头

下面提供两种实用方案,实现分组表头显示无Card记录数的需求:

方法一:使用值转换器快速实现统计

无需大幅改动现有ViewModel,通过XAML+转换器实现分组内无Card记录数统计。

步骤1:创建统计值转换器

编写IValueConverter实现类,遍历分组项统计无Card的记录数量:

using System;
using System.Collections;
using System.Globalization;
using System.Linq;
using System.Windows.Data;

// 替换为你的实际数据模型类型
public class ItemModel
{
    public string Group { get; set; }
    public string Card { get; set; }
}

public class NoCardCountConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // 强类型转换提升性能
        if (value is IEnumerable<ItemModel> items)
        {
            return items.Count(item => string.IsNullOrEmpty(item.Card));
        }

        // 兼容非强类型场景(通过反射处理)
        if (value is IEnumerable rawItems)
        {
            int count = 0;
            foreach (var item in rawItems)
            {
                var cardProp = item.GetType().GetProperty("Card");
                if (cardProp != null)
                {
                    var cardValue = cardProp.GetValue(item);
                    if (cardValue == null || string.IsNullOrEmpty(cardValue.ToString()))
                    {
                        count++;
                    }
                }
            }
            return count;
        }

        return 0;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

步骤2:修改XAML引用转换器并更新表头

在现有XAML中添加转换器资源,修改分组表头布局以显示统计值:

<Grid>
    <Grid.Resources>
        <!-- 注册转换器 -->
        <local:NoCardCountConverter x:Key="NoCardCountConverter"/>
        <CollectionViewSource x:Key="GroupItem" Source="{Binding Items}">
            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="Group" />
            </CollectionViewSource.GroupDescriptions>
        </CollectionViewSource>
    </Grid.Resources>
    
    <DataGrid x:Name="dataGrid1" 
              ItemsSource="{Binding Source={StaticResource GroupItem}}"
              CanUserAddRows="False">
        <DataGrid.GroupStyle>
            <GroupStyle>
                <GroupStyle.ContainerStyle>
                    <Style TargetType="{x:Type GroupItem}">
                        <Setter Property="Margin" Value="0,0,0,5"/>
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type GroupItem}">
                                    <Expander IsExpanded="True" Background="Yellow" >
                                        <Expander.Header>
                                            <StackPanel Orientation="Horizontal">
                                                <TextBlock Text="{Binding Name}" Margin="0,0,20,0"/>
                                                <TextBlock Text="总记录数: "/>
                                                <TextBlock Text="{Binding ItemCount}" Margin="0,0,20,0"/>
                                                <TextBlock Text="无Card记录数: "/>
                                                <!-- 绑定分组Items并通过转换器获取统计值 -->
                                                <TextBlock Text="{Binding Items, Converter={StaticResource NoCardCountConverter}}"/>
                                            </StackPanel>
                                        </Expander.Header>
                                        <Expander.Content>
                                            <ItemsPresenter />
                                        </Expander.Content>
                                    </Expander>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </GroupStyle.ContainerStyle>
            </GroupStyle>
        </DataGrid.GroupStyle>
    </DataGrid>
</Grid>

方法二:ViewModel自定义分组模型(性能更优)

如果数据量较大或需要更多统计项,建议提前在ViewModel计算统计值,避免UI层遍历开销。

步骤1:创建自定义分组模型

定义包含统计信息的分组类:

using System.Collections.ObjectModel;

public class ItemModel
{
    public string Group { get; set; }
    public string Card { get; set; }
}

public class CustomItemGroup
{
    public string GroupName { get; set; }
    public ObservableCollection<ItemModel> Items { get; set; } = new();
    public int TotalCount { get; set; }
    public int NoCardCount { get; set; }
}

步骤2:ViewModel中处理分组与统计

加载数据时手动分组并计算统计值:

using System.Collections.ObjectModel;
using System.Linq;

public class MainViewModel
{
    public ObservableCollection<CustomItemGroup> GroupedItems { get; set; } = new();

    public void LoadData()
    {
        // 模拟原始数据
        var rawItems = new ObservableCollection<ItemModel>
        {
            new ItemModel { Group = "分组A", Card = "123" },
            new ItemModel { Group = "分组A", Card = null },
            new ItemModel { Group = "分组B", Card = "" },
            // 更多数据...
        };

        // 分组并计算统计值
        var groupedData = rawItems.GroupBy(item => item.Group)
                                  .Select(group => new CustomItemGroup
                                  {
                                      GroupName = group.Key,
                                      Items = new ObservableCollection<ItemModel>(group),
                                      TotalCount = group.Count(),
                                      NoCardCount = group.Count(item => string.IsNullOrEmpty(item.Card))
                                  });

        foreach (var group in groupedData)
        {
            GroupedItems.Add(group);
        }
    }
}

步骤3:修改XAML绑定自定义分组

直接绑定分组模型的属性,无需转换器:

<Grid>
    <DataGrid x:Name="dataGrid1" 
              ItemsSource="{Binding GroupedItems}"
              CanUserAddRows="False">
        <DataGrid.GroupStyle>
            <GroupStyle>
                <GroupStyle.ContainerStyle>
                    <Style TargetType="{x:Type GroupItem}">
                        <Setter Property="Margin" Value="0,0,0,5"/>
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type GroupItem}">
                                    <Expander IsExpanded="True" Background="Yellow" >
                                        <Expander.Header>
                                            <StackPanel Orientation="Horizontal">
                                                <TextBlock Text="{Binding GroupName}" Margin="0,0,20,0"/>
                                                <TextBlock Text="总记录数: "/>
                                                <TextBlock Text="{Binding TotalCount}" Margin="0,0,20,0"/>
                                                <TextBlock Text="无Card记录数: "/>
                                                <TextBlock Text="{Binding NoCardCount}"/>
                                            </StackPanel>
                                        </Expander.Header>
                                        <Expander.Content>
                                            <DataGrid ItemsSource="{Binding Items}" 
                                                      AutoGenerateColumns="True" 
                                                      CanUserAddRows="False"/>
                                        </Expander.Content>
                                    </Expander>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </GroupStyle.ContainerStyle>
            </GroupStyle>
        </DataGrid.GroupStyle>
    </DataGrid>
</Grid>

内容的提问来源于stack exchange,提问作者Jasur1177

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 08:45:21