C# 群体统计

C# 群体统计,c#,wpf,datagrid,grouping,C#,Wpf,Datagrid,Grouping,我想使用下面的分组创建DataGrid 我的问题是如何在组标题中实现“平均值” 下面是一个巨大的xaml <DataGrid x:Name="dataGrid" Grid.Column="1" CanUserResizeRows="False" CanUserSortColumns="False" GridLinesVisibility="None" AutoGenerateColumns="False" ItemsSource="{Binding List}" HeadersV

我想使用下面的分组创建
DataGrid

我的问题是如何在组标题中实现“平均值”

下面是一个巨大的xaml

    <DataGrid x:Name="dataGrid" Grid.Column="1" CanUserResizeRows="False" CanUserSortColumns="False" GridLinesVisibility="None" AutoGenerateColumns="False" ItemsSource="{Binding List}" HeadersVisibility="Column" Grid.IsSharedSizeScope="True">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding A}" Header="A"/>
            <DataGridTextColumn Binding="{Binding B}" Header="B"/>
            <DataGridTextColumn Binding="{Binding C}" Header="C"/>
            <DataGridTextColumn Binding="{Binding Group}" Header="Group"/>
        </DataGrid.Columns>
        <DataGrid.GroupStyle>
            <GroupStyle>
                <GroupStyle.ContainerStyle>
                    <Style TargetType="GroupItem">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="GroupItem">
                                    <Border BorderBrush="Gray" BorderThickness="0.5" CornerRadius="4" Margin="3">
                                        <Border.Background>
                                            <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
                                                <GradientStop Color="#FFACACAC" Offset="0"/>
                                                <GradientStop Color="White" Offset="1"/>
                                            </LinearGradientBrush>
                                        </Border.Background>
                                        <StackPanel>
                                            <Grid>
                                                <Grid.ColumnDefinitions>
                                                    <ColumnDefinition SharedSizeGroup="A"/>
                                                    <ColumnDefinition SharedSizeGroup="B"/>
                                                    <ColumnDefinition/>
                                                </Grid.ColumnDefinitions>
                                                <TextBlock Text="{Binding Name}" Margin="10,0,10,0"/>
                                                <TextBlock Grid.Column="1" Text="{Binding ItemCount}" Margin="10,0,0,0"/>
                                                <TextBlock Grid.Column="2" Text="test" Margin="10,0,0,0"/>
                                            </Grid>
                                            <Expander>
                                                <Border BorderBrush="Gray" BorderThickness="0.5" Margin="3">
                                                    <ItemsPresenter/>
                                                </Border>
                                            </Expander>
                                        </StackPanel>
                                    </Border>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </GroupStyle.ContainerStyle>
            </GroupStyle>
        </DataGrid.GroupStyle>
    </DataGrid>

它产生这个输出

我可以输出组名(绿色箭头)和计数器(红色箭头)


如何输出任一列的平均值(设为
A
)而不是“test”?

您需要一个转换器将
属性转换为平均值。大概是这样的:

public class ItemsToAverageConverter : IValueConverter {
  public object Convert(object value, Type targetType, object parameter,
                                                       CultureInfo culture){
    var propName = Convert.ToString(parameter);
    var items = (IEnumerable<Item>) value;
    var prop = typeof(Item).GetProperty(propName);
    if(prop == null) return Binding.DoNothing;
    return items.Average(i => (double) prop.GetValue(i));
  }
  public object Convert(object value, Type targetType, object parameter,
                                                       CultureInfo culture){
    throw new NotImplementedException();
  }
}
<TextBlock Grid.Column="1" Text="{Binding Items,
                                  Converter={StaticResource avgConverter},
                                  ConverterParameter=A,
                                  StringFormat=f2}" Margin="10,0,0,0"/>
应按如下方式更改代码:

public class ItemsToAverageConverter : IValueConverter {
  public object Convert(object value, Type targetType, object parameter,
                                                       CultureInfo culture){
    var propName = Convert.ToString(parameter);
    var items = (IEnumerable<Item>) value;
    var prop = typeof(Item).GetProperty(propName);
    if(prop == null) return Binding.DoNothing;
    return items.Average(i => (double) prop.GetValue(i));
  }
  public object Convert(object value, Type targetType, object parameter,
                                                       CultureInfo culture){
    throw new NotImplementedException();
  }
}
<TextBlock Grid.Column="1" Text="{Binding Items,
                                  Converter={StaticResource avgConverter},
                                  ConverterParameter=A,
                                  StringFormat=f2}" Margin="10,0,0,0"/>


给定代码中几乎没有错误(
ConvertBack
,Cast,
Convert.ToString
,可能更多-我将反射简化为
switch/case
,因此没有尝试运行完整的示例),但给出了如何实现这一点的想法。谢谢剩下的唯一问题是,如果
项可以更改,该怎么办?当组项目发生更改时,是否有一种简单的方法刷新统计信息?目前看来,在创建组时,值仅转换一次
CollectionView.Refresh()
可以工作,但这是一种残酷的方式,我必须处理编辑等。因为我第一次使用转换器(!),我发现它非常有用(可以减少xaml噪音)。同样在
StringFormat={}{0:f2}
中,你可以像这样转义括号
StringFormat={0.00\}
,我相信这比
{}
修复更清楚。@Sinatr是的,至少有两种转义方法,我还知道第二种方法。