Я связываю CollectionViewSource
с ListView
, чтобы группировать предметы. Все прекрасно работает, за исключением случаев, когда я обновляю ObservableCollection
, на котором основан CollectionViewSource
. Если я обновляю значение объекта в коллекции, пользовательский интерфейс никогда не обновляется. Вот пример:
<ListView x:Name="MyListView" Margin="0,0,0,65">
<ListView.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" BorderBrush="#FFA4B97F" BorderThickness="0,0,0,1">
<Expander.Header>
<DockPanel>
<TextBlock FontWeight="Bold" Text="{Binding Name}" Margin="5,0,0,0" Width="80"/>
<TextBlock FontWeight="Bold" Width="60" TextAlignment="Center" Margin="16,0,0,0" Text="{Binding Items, Converter={StaticResource Converter2}}" />
</DockPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
<ListView.View>
<GridView>
<GridViewColumn Width="300" Header="Amount" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Amount}" Margin="80,0,0,0"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Вы заметите, что он вызывает конвертер в группе и дает ему коллекцию предметов. Таким образом, конвертер может вычислить среднее значение строк и вернуть результат:
public class AverageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
IEnumerable<object> rows = (IEnumerable<object>) value;
double average = rows.Average(a => ((DisplayRow) a).Amount);
return average;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
В коде позади я добавляю строки и создаю CollectionViewSource
:
приватный только для чтения ObservableCollection displayRows = new ObservableCollection ();
public Window1()
{
InitializeComponent();
displayRows.Add(new DisplayRow { Title = "Sales", Amount=16} );
displayRows.Add(new DisplayRow { Title = "Marketing", Amount=14} );
displayRows.Add(new DisplayRow { Title = "Technology", Amount=13} );
displayRows.Add(new DisplayRow { Title = "Sales", Amount=11} );
displayRows.Add(new DisplayRow { Title = "Marketing", Amount=13} );
displayRows.Add(new DisplayRow { Title = "Technology", Amount=12} );
CollectionViewSource viewSource = new CollectionViewSource { Source = displayRows };
viewSource.GroupDescriptions.Add(new PropertyGroupDescription("Title"));
MyListView.ItemsSource = viewSource.View;
}
Объект DisplayRow
реализует INotifyPropertyChanged
и представляет собой простой класс.
Все работает хорошо, и дисплей работает так, как я хочу, но если я изменю значение в ObservableCollection
, пользовательский интерфейс не изменится.
Если я добавляю элемент в коллекцию, я вижу, что он появляется на экране, но никогда не вызывается конвертер для пересчета среднего. Есть идеи?