在ObservableCollection上使用CollectionViewSource对Listbox进行实时排序

本文关键字:Listbox 实时 排序 CollectionViewSource ObservableCollection | 更新日期: 2023-09-27 18:02:02

我想启用绑定到ObservableCollection的ListBox项目的实时排序;我还想通过我的XAML标记(如果可能的话)单独启用实时排序。目前的情况是,列表在应用程序启动时被正确排序,但是当新项目被添加到ObservableCollection中时,项目只是简单地附加(而不是排序)到ListBox。

在我的视图模型我有以下公共属性:

public ObservableCollection<Equipment> EquipmentList { get; set; }

Equipment是一个来自实体框架的自动生成的类,它包含一个名为'Description'的公共字符串属性。这是我的排序目标。

我的XAML有以下DataTemplate,它旨在启用实时排序:

<DataTemplate x:Key="EquipmentDescriptionTemplate" 
                      DataType="{x:Type e:Equipment}">
    <DataTemplate.Resources>
        <CollectionViewSource x:Key="SortedEquipmentList" 
                              Source="{Binding Path=Description, 
                                  Mode=OneWay, 
                                  UpdateSourceTrigger=PropertyChanged}" 
                                  IsLiveSortingRequested="True">
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName="Description" 
                                     Direction="Ascending"/>
            </CollectionViewSource.SortDescriptions>
            <CollectionViewSource.LiveSortingProperties>
                <clr:String>Description</clr:String>
            </CollectionViewSource.LiveSortingProperties>
        </CollectionViewSource>
    </DataTemplate.Resources>
    <TextBlock Text="{Binding Path=Description}" />
</DataTemplate>
最后是XAML ListBox项目:
<ListBox x:Name="EquipmentList" 
     ItemsSource="{Binding Path=EquipmentList, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" 
     ItemTemplate="{StaticResource EquipmentDescriptionTemplate}" 
     IsSynchronizedWithCurrentItem="True" 
     SelectedItem="{Binding EquipmentSelection, UpdateSourceTrigger=PropertyChanged}" 
     Grid.ColumnSpan="2" Grid.Row="1" Margin="5,5,5,5"/>

有很多额外的属性是我在不顾一切地尝试让实时排序工作时添加的(当有疑问时,大胆猜测!)。我把它们留在这里,这样人们就可以看到我的尝试,并窃笑。

我如何通过XAML启用实时列表框排序?

在ObservableCollection上使用CollectionViewSource对Listbox进行实时排序

您需要将ItemsSource绑定到CollectionViewSource,而不是底层集合:

<ListBox x:Name="EquipmentList" 
         ItemsSource="{StaticResource SortedEquipmentList}" 
         ...
         />

将CollectionViewSource放在页面资源字典的上方某处。将其源绑定到底层集合("EquipmentList"):

<CollectionViewSource x:Key="SortedEquipmentList" 
                      Source="{Binding EquipmentList.View}" 
                      IsLiveSortingRequested="True">
    <CollectionViewSource.SortDescriptions>
        <scm:SortDescription PropertyName="Description" Direction="Ascending"/>
    </CollectionViewSource.SortDescriptions>
    <CollectionViewSource.LiveSortingProperties>
        <clr:String>Description</clr:String>
    </CollectionViewSource.LiveSortingProperties>
</CollectionViewSource>