问题
I have a CollectionViewSource CollectionOfVideos
bound to ObservableCollection ListOfVideos
. That CollectionViewSource is the ItemsSource for the DataGrid dataGrid_Video
. I've implemented a grouping by lShortName
of label
of ListOfVideos
. When items are added to DataGrid, grouping seems to work, because it groups all added items by their default label
.
Problem is, grouping doesn't update when label
of item is changed. Here's my code:
Window.Resources in MainWindow.xaml
<CollectionViewSource x:Key="CollectionOfVideos" Source="{Binding fosaModel.ListOfVideos, UpdateSourceTrigger=PropertyChanged}" IsLiveGroupingRequested="True" IsLiveSortingRequested="True" >
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="label" Converter="{StaticResource LTSConverter}"/>
</CollectionViewSource.GroupDescriptions>
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="label.lShortName"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
dataGrid_Video in MainWindow.xaml
<DataGrid x:Name="dataGrid_Video"
AutoGenerateColumns="False"
Margin="0,0,0,0"
Grid.Row="1"
ItemsSource="{Binding Source={StaticResource CollectionOfVideos}}"
GridLinesVisibility="Horizontal"
SelectedItem="{Binding fosaModel.SelectedVideo}"
SelectedIndex="{Binding fosaModel.SelectedVideoIndex}"
SelectionUnit="FullRow"
SelectionMode="Single">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding fName}" Header="Nazwa" IsReadOnly="True"></DataGridTextColumn>
<DataGridTextColumn Binding="{Binding AudioToSync}" Header="Dźwięk"></DataGridTextColumn>
</DataGrid.Columns>
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
</DataGrid>
Here's my fosaModel
public class fosaModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public ObservableCollection<fosaVideo> ListOfVideos { get; set; } = new ObservableCollection<fosaVideo>();
public ObservableCollection<fosaAudio> ListOfAudios { get; set; } = new ObservableCollection<fosaAudio>();
public ObservableCollection<fosaLabel> ListOfLabels { get; set; } = new ObservableCollection<fosaLabel>();
public fosaVideo SelectedVideo { get; set; }
public int SelectedVideoIndex { get; set; } = -1;
public fosaAudio SelectedAudio { get; set; }
public int SelectedAudioIndex { get; set; } = -1;
public fosaLabel SelectedLabel { get; set; }
public int SelectedLabelIndex { get; set; } = -1;
public string WorkingDir { get; set; } = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
public double videoProgress { get; set; }
public int SliderValue { get; set; }
public bool IsDialogClosed { get; set; } = true;
}
There are few things you should know:
- I use Fody.PropertyChanged, so it's not PropertyChanged notification problem. Adding new items to the list updates the DataGrid.
- Sorting doesn't work either.
- Changing
label
of particular item inListOfVideos
does work, I checked in Debug - I thought it was a problem with dot notation of
PropertyName
in GroupingDescriptions, so I've added a converter. With or without converter - problem still exists. - There is also very similar CollectionViewSource, with sorting implemented, and it works on adding new item.
- I use MVVM Light and I'd like to keep it MVVM way.
回答1:
You should add the names of the properties to live group by to the LiveGroupingProperties collection of the CollectionViewSource:
<CollectionViewSource x:Key="CollectionOfVideos" Source="{Binding fosaModel.ListOfVideos, UpdateSourceTrigger=PropertyChanged}"
IsLiveGroupingRequested="True" IsLiveSortingRequested="True"
xmlns:s="clr-namespace:System;assembly=mscorlib">
<CollectionViewSource.LiveGroupingProperties>
<s:String>label</s:String>
</CollectionViewSource.LiveGroupingProperties>
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="label" Converter="{StaticResource LTSConverter}"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
It's the same for the live sorting: https://wpf.2000things.com/2014/01/16/988-enabling-live-sorting-in-a-collectionviewsource/
I don't think this will work with nested properties such as "label.lShortName" though so if you want to live sort by a sub-property of the type T
in your ObservableCollection<T>
you need to add a property to the type T
that wraps the sub-property, e.g.:
public string lShortName
{
get { return label.lShortName; }
set { label.lShortName = value; NotifyPropertyChanged(); }
}
来源:https://stackoverflow.com/questions/41515053/datagrid-grouping-doesnt-update-on-change-in-collectionviewsource