Je lie un CollectionViewSource
à un ListView
pour regrouper des éléments. Tout fonctionne très bien sauf quand je mets à jour le ObservableCollection
sur lequel est basé CollectionViewSource
. Si je mets à jour une valeur d'un objet dans la collection, l'interface utilisateur n'est jamais mise à jour. Voici un exemple:Groupement WPF à l'aide de CollectionViewSource et DataBinding
<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>
Vous remarquerez qu'il appelle un convertisseur dans le groupe et en lui donnant la collection d'éléments. Il en est ainsi le convertisseur peut calculer la moyenne des lignes et retourner ce résultat:
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();
}
}
Dans le code derrière ajouter les lignes et créer le CollectionViewSource
:
readonly privé 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;
}
L'objet DisplayRow
implémente INotifyPropertyChanged
, et est juste une simple classe.
Tout fonctionne bien et l'affichage est comme je veux, mais si je change une valeur dans le ObservableCollection
l'interface utilisateur ne change pas.
Si j'ajoute un élément à la collection je peux le voir apparaître sur l'écran mais le convertisseur n'est jamais appelé pour recalculer la moyenne. Des idées?
Nice. Oui, ça aide. Malheureusement, j'ai besoin de mettre à jour le tout, mais au moins, cela me cause ce problème. Merci. – Kelly