I have an ItemsControl
which is bound to a CollectionViewSource
bound to a property on the View Model.
The ItemsControl
has a GroupStyle
set which looks like this:
<GroupStyle HeaderTemplate="{StaticResource TotalDurationTemplate}" />
Where TotalDurationTemplate
is:
<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>
The issue is that the second TextBlock
(the one bound to Items
) is not re-evaluated when a new item is added to the View Model's collection (which is an ObservableCollection<>
). The item is added to the ListView
into the correct group but the Total Duration value is not updated.
The Converter for Total Duration looks like this:
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();
}
}
How do I make the binding refresh correctly when the items in the View Model are changed?
EDIT: The Solution
I took Solution 2 from the Accepted Answer and put it into my code. This is what ended up working:
<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>
And changing TotalDurationConverter
to IMultiValueConverter
. The just ignore the second item in the Array
.