CollectionViewSource使用默认和备份源进行排序

时间:2012-06-11 14:28:30

标签: wpf sorting collectionviewsource

我正在制定一个计划程序,其中项目具有计划日期,但用户可以选择将其覆盖为他们选择的日期。为了实现这一点,我的Item对象使用两个属性:ScheduledDate(DateTime)和ActualDate(DateTime?)。因此,如果ActualDate属性为null,则用户尚未覆盖此项的计划。

在我的一个视图中,我需要在ListBox中显示这些项目,并按实际日期排序。我遇到的麻烦是如何使用这两个属性实现CollectionViewSource

我知道这不正确,但我需要这样的事情:

<CollectionViewSource x:Key="TransactionsViewSource"
                      Source="{Binding ElementName=ThisControl, 
                                       Path=Items}">
    <CollectionViewSource.SortDescriptions>
        <cm:SortDescription PropertyName="ActualDate ?? ScheduledDate"/>
    </CollectionViewSource.SortDescriptions>
</CollectionViewSource>

(ThisControl是托管UserControl的{​​{1}}的名称。)

如果我添加第二个SortDescriptor(如下所示),我会得到一个按ActualDate排序的列表,然后是Scheduled Date,它将所有被覆盖的项目组合在一起。这不是理想的行为。

ListBox

感谢。

2 个答案:

答案 0 :(得分:1)

我最终在我的UserControl类中创建了一个新方法,该方法使用LINQ来保持基础ObservableCollection的排序。然后,每当编辑项目(实际日期被覆盖)或添加新项目时,我都会调用此方法。最后,我从XAML中删除了CollectionViewSource并将ListBox绑定到Items属性(我已将其作为依赖属性)。结果如下:

XAML:

<ListBox ItemsSource="{Binding ElementName=ThisControl,
                               Path=Items}"/>

C#:

public static readonly DependencyProperty ItemsProperty =
    DependencyProperty.Register("Items",
                                typeof(ObservableCollection<MyItem>),
                                typeof(MyControl),
                                new UIPropertyMetadata(null));

public ObservableCollection<MyItem> Items
{
    get { return (ObservableCollection<MyItem>) GetValue(ItemsProperty); }
    set { SetValue(ItemsProperty, value); }
}

private void SortItems()
{
    Items = new ObservableCollection<MyItem>(Items.OrderBy(i => i.ActualDate ??
                                                                i.ScheduledDate));
}

然后我只在集合中的项目或集合本身发生变化的任何地方使用SortItems()

它完美无缺,我不必创建和管理新属性。我可以忍受LINQ创建的一点点开销。

答案 1 :(得分:0)

我认为最简单的方法是为排序创建一个属性:

public DateTime SortingDate
{
    get { return ActualDate ?? ScheduledDate; }
}

<CollectionViewSource.SortDescriptions>
    <cm:SortDescription PropertyName="SortingDate"/>
</CollectionViewSource.SortDescriptions>