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
相关产品推荐
相关产品推荐

