0

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

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

我知道这是不正确的,但我需要这样的东西:

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

(ThisControl 是UserControl承载. 的名称ListBox。)

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

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

谢谢。

4

2 回答 2

1

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

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 产生的一点点开销。

于 2012-06-12T03:55:35.493 回答
0

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

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

.

<CollectionViewSource.SortDescriptions>
    <cm:SortDescription PropertyName="SortingDate"/>
</CollectionViewSource.SortDescriptions>
于 2012-06-11T23:34:17.527 回答