DataGrid 分组不会随着 CollectionViewSource 的变化而更新
DataGrid grouping doesn't update on change in CollectionViewSource
我有一个 CollectionViewSource CollectionOfVideos
绑定到 ObservableCollection ListOfVideos
。该 CollectionViewSource 是 DataGrid dataGrid_Video
的 ItemsSource。我已经按 lShortName
of label
of ListOfVideos
实施了分组。将项目添加到 DataGrid 时,分组似乎起作用了,因为它按默认 label
.
对所有添加的项目进行分组
问题是,当项目的 label
发生变化时,分组不会更新。这是我的代码:
Window.Resources 在 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 在 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>
这是我的 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;
}
有几件事你应该知道:
- 我用的是Fody.PropertyChanged,所以不是PropertyChanged通知的问题。向列表中添加新项目会更新 DataGrid。
- 排序也不行。
- 更改
ListOfVideos
中特定项目的 label
确实有效,我检查了 Debug
- 我认为 GroupingDescriptions 中
PropertyName
的点符号有问题,所以我添加了一个转换器。有或没有转换器 - 问题仍然存在。
- 还有非常相似的 CollectionViewSource,实现了排序,并且可以添加新项目。
- 我使用 MVVM Light,我想保持 MVVM 的方式。
您应该将属性的名称添加到 CollectionViewSource 的 LiveGroupingProperties 集合中:
<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>
现场排序也是一样:https://wpf.2000things.com/2014/01/16/988-enabling-live-sorting-in-a-collectionviewsource/
我认为这不适用于 "label.lShortName" 等嵌套属性,所以如果您想按 T
类型的子 属性 排序ObservableCollection<T>
你需要在类型 T
中添加一个 属性 来包裹子 属性,例如:
public string lShortName
{
get { return label.lShortName; }
set { label.lShortName = value; NotifyPropertyChanged(); }
}
我有一个 CollectionViewSource CollectionOfVideos
绑定到 ObservableCollection ListOfVideos
。该 CollectionViewSource 是 DataGrid dataGrid_Video
的 ItemsSource。我已经按 lShortName
of label
of ListOfVideos
实施了分组。将项目添加到 DataGrid 时,分组似乎起作用了,因为它按默认 label
.
问题是,当项目的 label
发生变化时,分组不会更新。这是我的代码:
Window.Resources 在 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 在 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>
这是我的 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;
}
有几件事你应该知道:
- 我用的是Fody.PropertyChanged,所以不是PropertyChanged通知的问题。向列表中添加新项目会更新 DataGrid。
- 排序也不行。
- 更改
ListOfVideos
中特定项目的label
确实有效,我检查了 Debug - 我认为 GroupingDescriptions 中
PropertyName
的点符号有问题,所以我添加了一个转换器。有或没有转换器 - 问题仍然存在。 - 还有非常相似的 CollectionViewSource,实现了排序,并且可以添加新项目。
- 我使用 MVVM Light,我想保持 MVVM 的方式。
您应该将属性的名称添加到 CollectionViewSource 的 LiveGroupingProperties 集合中:
<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>
现场排序也是一样:https://wpf.2000things.com/2014/01/16/988-enabling-live-sorting-in-a-collectionviewsource/
我认为这不适用于 "label.lShortName" 等嵌套属性,所以如果您想按 T
类型的子 属性 排序ObservableCollection<T>
你需要在类型 T
中添加一个 属性 来包裹子 属性,例如:
public string lShortName
{
get { return label.lShortName; }
set { label.lShortName = value; NotifyPropertyChanged(); }
}