Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# CollectionViewGroup.Items是否在添加项目后未引发属性更改?_C#_Wpf_Data Binding_Datagrid - Fatal编程技术网

C# CollectionViewGroup.Items是否在添加项目后未引发属性更改?

C# CollectionViewGroup.Items是否在添加项目后未引发属性更改?,c#,wpf,data-binding,datagrid,C#,Wpf,Data Binding,Datagrid,我正在尝试向DataGrid中添加带有小计的分组。阅读几篇文章:解决方案是使用数据创建一个ObservableCollection,将其包装到CollectionViewSource中,然后将其作为数据网格的ItemsSource。使用转换器计算小计,该转换器接收CollectionViewGroup的项作为输入,并计算总和 只有在可观测集合的初始填充时或添加项目创建新组时,“所有”都可以正常工作。但是如果一个项目被添加到任何现有的组中,转换器就不会被调用进行重新计算-显然是Collection

我正在尝试向DataGrid中添加带有小计的分组。阅读几篇文章:解决方案是使用数据创建一个
ObservableCollection
,将其包装到
CollectionViewSource
中,然后将其作为数据网格的
ItemsSource
。使用转换器计算小计,该转换器接收
CollectionViewGroup
项作为输入,并计算总和

只有在
可观测集合的初始填充时或添加项目创建新组时,“所有”都可以正常工作。但是如果一个项目被添加到任何现有的组中,转换器就不会被调用进行重新计算-显然是
CollectionViewGroup.Items
没有引发
PropertyChanged
事件? 我在-
中浏览了一些项目
ReadOnlyObservableCollection
,它应该在添加项目后触发
属性更改
,不是吗

然后我注意到,
CollectionViewGroup.ItemCount
在添加新项目后正确显示,因此我尝试了一个
MultiBinding
的技巧-添加了一个
IMultiValueConverter
转换器,它将
项目
ItemCount
作为参数,期望
ItemCount
触发重新计算。它成功了,但同样没有完全成功——在创建新组时,转换器只获得一次正确的输入。如果将项目添加到现有组,
ItemCount
是正确的,但
Items
不是<代码>项目
集合缺少新添加的项目! 例如,当
项目计数
=2时,
项目
只有1个“旧”项目(
项目.计数
=1)。当
ItemCount
=3时,
Items
只有2个“旧”项(
Items.Count
=2),等等。因此转换器同样无法计算正确的小计,因为输入不完整

看起来唯一可行的解决方案是为整个
CollectionViewSource
调用
Refresh()
,但这会扩展所有组,导致闪烁,破坏MVVM概念,因此很难看

因此,我的问题是:

  • 是否仍有任何更改要进行
    CollectionViewGroup.Items
    raise
    PropertyChanged
    正确更改

  • 多转换器接收
    项。计数
    =
    ItemCount
    -1,这不是
    CollectionViewGroup
    中的一个错误吗

任何建议都将不胜感激

完整的示例代码已打开

下面是一些代码摘录- XAML

            <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" BorderThickness="1,1,1,5">
                                        <Expander.Header>
                                            <DockPanel>
                                                <TextBlock FontWeight="Bold" Text="{Binding Path=Name}" Margin="5,0,0,0" Width="100"/>
                                                <TextBlock FontWeight="Bold" Text="{Binding Path=ItemCount}"/>
                                                <TextBlock FontWeight="Bold" Text="Sum 1: " Margin="5,0,0,0"/>
                                                <TextBlock FontWeight="Bold"  >
                                                    <TextBlock.Text>
                                                        <Binding Path="Items" Converter="{StaticResource sumConverter}" ConverterParameter="AmountValue" StringFormat="{}{0:N2}"/>
                                                    </TextBlock.Text>
                                                </TextBlock>
                                                <TextBlock FontWeight="Bold" Text="Sum 2: " Margin="5,0,0,0"/>
                                                <TextBlock FontWeight="Bold"  >
                                                    <TextBlock.Text>
                                                        <MultiBinding Converter="{StaticResource sumMulConverter}" ConverterParameter="AmountValue" StringFormat="{}{0:N2}">
                                                            <Binding Path="Items"/>
                                                            <Binding Path="ItemCount"/>
                                                        </MultiBinding>
                                                    </TextBlock.Text>
                                                </TextBlock>
                                            </DockPanel>
                                        </Expander.Header>
                                        <Expander.Content>
                                            <ItemsPresenter />
                                        </Expander.Content>
                                    </Expander>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </GroupStyle.ContainerStyle>
            </GroupStyle>
        </DataGrid.GroupStyle>
    public class SumConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == DependencyProperty.UnsetValue) return DependencyProperty.UnsetValue;
        if (null == parameter) return null;
        string propertyName = (string)parameter;
        if (!(value is ReadOnlyObservableCollection<object>)) return null;
        ReadOnlyObservableCollection<object> collection = (ReadOnlyObservableCollection<object>)value;
        decimal sum = 0;
        foreach (object o in collection)
        {
            sum += (decimal)o.GetType().GetProperty(propertyName).GetValue(o);
        }
        return sum;
    }

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

public class SumMulConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (null == parameter) return null;
        if (!(parameter is string)) return null;
        string propertyName = (string)parameter;

        if (values == DependencyProperty.UnsetValue) return DependencyProperty.UnsetValue;
        if (values == null) return null;
        if (values.Length < 2) return null;
        if (!(values[0] is ReadOnlyObservableCollection<object>)) return null;
        ReadOnlyObservableCollection<object> collection = (ReadOnlyObservableCollection<object>)values[0];
        if (!(values[1] is int)) return null;
        Debug.Print($"ItemCount={(int)values[1]}; Collection Count = {collection.Count}");
        decimal sum = 0;
        foreach (object o in collection)
        {
            sum += (decimal)o.GetType().GetProperty(propertyName).GetValue(o);
        }
        return sum; //.ToString("N2", CultureInfo.CurrentCulture);
    }

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

转换器

            <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" BorderThickness="1,1,1,5">
                                        <Expander.Header>
                                            <DockPanel>
                                                <TextBlock FontWeight="Bold" Text="{Binding Path=Name}" Margin="5,0,0,0" Width="100"/>
                                                <TextBlock FontWeight="Bold" Text="{Binding Path=ItemCount}"/>
                                                <TextBlock FontWeight="Bold" Text="Sum 1: " Margin="5,0,0,0"/>
                                                <TextBlock FontWeight="Bold"  >
                                                    <TextBlock.Text>
                                                        <Binding Path="Items" Converter="{StaticResource sumConverter}" ConverterParameter="AmountValue" StringFormat="{}{0:N2}"/>
                                                    </TextBlock.Text>
                                                </TextBlock>
                                                <TextBlock FontWeight="Bold" Text="Sum 2: " Margin="5,0,0,0"/>
                                                <TextBlock FontWeight="Bold"  >
                                                    <TextBlock.Text>
                                                        <MultiBinding Converter="{StaticResource sumMulConverter}" ConverterParameter="AmountValue" StringFormat="{}{0:N2}">
                                                            <Binding Path="Items"/>
                                                            <Binding Path="ItemCount"/>
                                                        </MultiBinding>
                                                    </TextBlock.Text>
                                                </TextBlock>
                                            </DockPanel>
                                        </Expander.Header>
                                        <Expander.Content>
                                            <ItemsPresenter />
                                        </Expander.Content>
                                    </Expander>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </GroupStyle.ContainerStyle>
            </GroupStyle>
        </DataGrid.GroupStyle>
    public class SumConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == DependencyProperty.UnsetValue) return DependencyProperty.UnsetValue;
        if (null == parameter) return null;
        string propertyName = (string)parameter;
        if (!(value is ReadOnlyObservableCollection<object>)) return null;
        ReadOnlyObservableCollection<object> collection = (ReadOnlyObservableCollection<object>)value;
        decimal sum = 0;
        foreach (object o in collection)
        {
            sum += (decimal)o.GetType().GetProperty(propertyName).GetValue(o);
        }
        return sum;
    }

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

public class SumMulConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (null == parameter) return null;
        if (!(parameter is string)) return null;
        string propertyName = (string)parameter;

        if (values == DependencyProperty.UnsetValue) return DependencyProperty.UnsetValue;
        if (values == null) return null;
        if (values.Length < 2) return null;
        if (!(values[0] is ReadOnlyObservableCollection<object>)) return null;
        ReadOnlyObservableCollection<object> collection = (ReadOnlyObservableCollection<object>)values[0];
        if (!(values[1] is int)) return null;
        Debug.Print($"ItemCount={(int)values[1]}; Collection Count = {collection.Count}");
        decimal sum = 0;
        foreach (object o in collection)
        {
            sum += (decimal)o.GetType().GetProperty(propertyName).GetValue(o);
        }
        return sum; //.ToString("N2", CultureInfo.CurrentCulture);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
公共类SumConverter:IValueConverter
{
公共对象转换(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性)
{
如果(value==dependencProperty.UnsetValue)返回dependencProperty.UnsetValue;
if(null==参数)返回null;
字符串propertyName=(字符串)参数;
如果(!(值为ReadOnlyObservableCollection))返回null;
ReadOnlyObservableCollection=(ReadOnlyObservableCollection)值;
十进制和=0;
foreach(集合中的对象o)
{
sum+=(十进制)o.GetType().GetProperty(propertyName).GetValue(o);
}
回报金额;
}
公共对象转换回(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性)
{
抛出新的NotImplementedException();
}
}
公共类SumMulConverter:IMultiValueConverter
{
公共对象转换(对象[]值,类型targetType,对象参数,CultureInfo区域性)
{
if(null==参数)返回null;
如果(!(参数为字符串))则返回null;
字符串propertyName=(字符串)参数;
如果(value==dependencProperty.UnsetValue)返回dependencProperty.UnsetValue;
if(value==null)返回null;
if(values.Length<2)返回null;
如果(!(值[0]为ReadOnlyObservableCollection))返回null;
ReadOnlyObservableCollection=(ReadOnlyObservableCollection)值[0];
如果(!(值[1]为int))返回null;
Debug.Print($”ItemCount={(int)值[1]}