我正在制定一个计划程序,其中项目具有计划日期,但用户可以选择将其覆盖为他们选择的日期。为了实现这一点,我的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
感谢。
答案 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>