我有一个可观察的集合,我使用 linq 对其进行排序。一切都很好,但我遇到的问题是如何对实际的 observable 集合进行排序?相反,我只是得到了一些 IEnumerable 的东西,我最终清除了集合并重新添加了东西。这对性能没有好处。有谁知道更好的方法来做到这一点?
6 回答
如果您使用的是 Silverlight 3.0,那么使用 CollectionViewSource 是最简洁的方法。请参考以下示例:(也可以通过 xaml 完成)
ObservableCollection<DateTime> ecAll = new ObservableCollection<DateTime>();
CollectionViewSource sortedcvs = new CollectionViewSource();
sortedcvs.SortDescriptions.Add(new System.ComponentModel.SortDescription("Date",
System.ComponentModel.ListSortDirection.Ascending));
sortedcvs.Source = ecAll;
ListBoxContainer.DataContext = sortedcvs;
并在相应的 xaml 集中
ItemsSource="{Binding}"
对于 ListBox 或任何 ItemsControl 派生控件
由于该集合不提供任何Sort
机制,因此这可能是最实用的选择。您可以使用 etc 手动实现排序Move
,但它可能会比以这种方式执行的要慢。
var arr = list.OrderBy(x => x.SomeProp).ToArray();
list.Clear();
foreach (var item in arr) {
list.Add(item);
}
此外,您可能会考虑在排序时取消绑定任何 UI 元素(通过任一方法),您只需支付重新绑定一次费用:
有趣的是,如果这是BindingList<T>
,您可以使用RaiseListChangedEvents
来最小化通知的数量:
var arr = list.OrderBy(x => x).ToArray();
bool oldRaise = list.RaiseListChangedEvents;
list.RaiseListChangedEvents = false;
try {
list.Clear();
foreach (var item in arr) {
list.Add(item);
}
} finally {
list.RaiseListChangedEvents = oldRaise;
if (oldRaise) list.ResetBindings();
}
请注意,在 Linq 中,您会从查询中获得一个 IEnumerable,并且该查询尚未执行。因此,以下代码只运行一次查询,将其添加到 ObservableCollection:
var query = from x in Data
where x.Tag == "Something"
select x;
foreach(var item in query)
MyObservableCollection.Add(item);
看看 IEnumerable 上的“ OrderBy ”扩展:
foreach(var item in query.OrderBy(x => x.Name))
MyObservableCollection.Add(item);
ObservableCollections 并非设计为可排序的。List 是可排序的,这是引用 List.Sort() 的答案所使用的底层机制,但 ObservableCollection 不是从 List 派生的,所以你在那里不走运。Imo,“正确”的解决方案不是尝试对 ObservableCollection 进行排序,而是实现 ICollectionView 并将其实例绑定到您的控件。该接口添加了用于排序的方法,并具有 Silverlight 控件(好吧,无论如何都支持它的控件,例如 DataGrid)识别的额外好处,因此您的排序可以直接从 UI 层使用。这个问题可能会有所帮助:
我按照这篇文章中提到的链接http://mokosh.co.uk/post/2009/08/04/how-to-sort-observablecollection/comment-page-1/#comment-75
但在 Silverlight 中运行时遇到问题
我创建了一个属性 public SortableObservableCollection 条款 当我调用 Terms.Sort(new TermComparer()) 时,记录仍然在 UI 上显示未排序
有人可以建议可能出了什么问题。谢谢