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) - 第二个虚拟 属性 将确保您的转换器被重新评估。
我想第二个选项应该适合你。
如果它不起作用,请告诉我。
此致,
维沙
我有一个 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) - 第二个虚拟 属性 将确保您的转换器被重新评估。
我想第二个选项应该适合你。
如果它不起作用,请告诉我。
此致, 维沙