collection 更改时未更新 GroupStyle header 中的绑定

Binding in GroupStyle header not updated when collection changes

我有一个 ItemsControl 绑定到 CollectionViewSource 绑定到视图模型上的 属性。

ItemsControl 有一个 GroupStyle 集合,如下所示:

<GroupStyle HeaderTemplate="{StaticResource TotalDurationTemplate}" />

其中 TotalDurationTemplate 是:

<DataTemplate x:Key="TotalDurationTemplate">
    <Border BorderBrush="Black" BorderThickness="0 1" Background="#EEE">
        <Grid>
            <TextBlock HorizontalAlignment="Center"
                                           FontSize="18" FontWeight="Bold"
                                           Text="{Binding Path=Items[0].Start, Converter={StaticResource DateTimeFormatConverter}, ConverterParameter='ddd dd/MM'}" />
            <TextBlock Margin="10 0" HorizontalAlignment="Right" VerticalAlignment="Center"
                                           FontSize="16" Foreground="#9000"
                                           Text="{Binding Items, Converter={StaticResource TotalDurationConverter}}" />
        </Grid>
    </Border>
</DataTemplate>

问题是第二个 TextBlock(绑定到 Items 的那个)不是 re-evaluated 当一个新项目被添加到视图模型的 collection (这是一个 ObservableCollection<>)。该项目已添加到 ListView 到正确的组中,但总持续时间值未更新。

总持续时间转换器如下所示:

public class TotalDurationConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return
            ((IEnumerable<object>)value)
                .Select(x => ((RecentTimingViewModel)x).Duration)
                .Aggregate((v1, v2) => v1 + v2)
                .TotalHours
                .ToString("F2") + "h";
    }

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

当视图模型中的项目发生变化时,如何使绑定正确刷新?

编辑:解决方案

我从已接受的答案中提取了解决方案 2 并将其放入我的代码中。这就是最终的工作:

<DataTemplate x:Key="TotalDurationTemplate">
    <Border BorderBrush="Black" BorderThickness="0 1" Background="#EEE">
        <Grid>
            <TextBlock HorizontalAlignment="Center"
                       FontSize="18" FontWeight="Bold"
                       Text="{Binding Path=Items[0].Start, Converter={StaticResource FormatDateIntelligentConverter}}" />
            <TextBlock Margin="10 0" HorizontalAlignment="Right" VerticalAlignment="Center"
                       FontSize="16" Foreground="#9000">
                <TextBlock.Text>
                    <MultiBinding Converter="{StaticResource TotalDurationConverter}">
                        <MultiBinding.Bindings>
                            <Binding Path="Items" />
                            <Binding Path="Items.Count" />
                        </MultiBinding.Bindings>
                    </MultiBinding>
                </TextBlock.Text>
            </TextBlock>
        </Grid>
    </Border>
</DataTemplate>

并将 TotalDurationConverter 更改为 IMultiValueConverter。只需忽略 Array.

中的第二项

所以有两种可能性,如果您可以尝试以下简单的解决方案,请告诉我是否可行。

解决方案 1 - 一个非常简单和基本的解决方案,因为您使用的是文本块,将模式明确设置为双向。我猜 TextBlock 默认绑定模式是一种方式。

解决方案 2 - 我在使用组合框时遇到了类似的问题 - 这是一个对我有用的解决方法 对于第二个文本块,使用多绑定,首先将它绑定到列表,就像你已经完成的那样,然后将它绑定到视图模型中的任何 属性 ,当你的列表发生变化时将被触发(例如 int 属性 返回 List.Count) - 第二个虚拟 属性 将确保您的转换器被重新评估。

我想第二个选项应该适合你。

如果它不起作用,请告诉我。

此致, 维沙