DataGrid分组不会更新CollectionViewSource

时间:2017-01-06 22:01:23

标签: c# wpf mvvm datagrid collectionviewsource

我有一个与ObservableCollection CollectionOfVideos绑定的CollectionViewSource ListOfVideos。 CollectionViewSource是DataGrid dataGrid_Video的ItemsSource。我已经lShortName label ListOfVideos实施了分组。将项目添加到DataGrid时,分组似乎有效,因为它按默认label对所有添加的项目进行分组。

问题是,当项目label更改时,分组不会更新。这是我的代码:

MainWindow.xaml中的Window.Resources

<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>

MainWindow.xaml中的dataGrid_Video

       <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。
  • 排序也不起作用。
  • 更改label中特定项目的ListOfVideos确实有效,我检查了调试
  • 我认为在GroupingDescriptions中PropertyName的点符号存在问题,所以我添加了一个转换器。有或没有转换器 - 问题仍然存在。
  • 还有一个非常相似的CollectionViewSource,实现了排序,它可以添加新项目。
  • 我使用MVVM Light,我想保持MVVM方式。

1 个答案:

答案 0 :(得分:1)

您应该将实时组的属性名称添加到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/

我不认为这适用于嵌套属性,例如&#34; label.lShortName&#34;尽管如此,如果您希望按TObservableCollection<T>类型的子属性进行排序,则需要将属性添加到包含子属性的类型T,例如:

public string lShortName
{
    get { return label.lShortName; }
    set { label.lShortName = value; NotifyPropertyChanged(); }
}