我正在构建Windows Phone 8.1(WinRt)应用程序。
我有一个ObservableCollection<object>
,我需要添加,修改和排序此集合的项目。
当我将一个项目添加到此列表时,一切正常,如果我在列表中投射此对象之一并编辑对象的属性INotifyPropertyChanged
负责更新ui。
但是当我对列表进行排序时,UI并不尊重列表的顺序。
更新用户界面的唯一方法是使用Move()
,但我发现这种方法很耗费资源。
我尝试过使用LINQ,但结果列表是有序的,但UI中的元素保持相同的顺序。
还有其他方法可以对此列表进行排序吗?
这是我的ViewModel
中的一些代码ActiveServices = ActiveServices.Where(x => x is ActiveServiceControlData).OrderByDescending(x => (x as ActiveServiceControlData).NotificationNumber).ToObservableCollection();
private static ObservableCollection<object> activeServices;
public ObservableCollection<object> ActiveServices
{
get { return activeServices; }
set
{
activeServices = value;
RaisePropertyChanged(() => ActiveServices);
}
}
修改
我的大问题是在ObservableCollection中有不同类型的对象,我使用此集合作为ListView的ItemsSource,其中ItemTemplateSelector基于ObservableCollection中对象的类型,我只需要对元素进行排序特定类型。
答案 0 :(得分:2)
对ObservableCollection
进行排序的正确方法是扩展基础ObservableCollection
并使用内部CollectionChanged
事件。
您当前的代码会重新创建效率低下的整个集合(并且您的用户界面可能会“闪烁”)。
public class SortableObservableCollection<T, TSortKey> : ObservableCollection<T>
{
private readonly Func<T, TKey> _sortByKey;
public SortableObservableCollection(Func<T, TKey> sortByKey)
{
_sortByKey = sortByKey;
}
public void Sort() {
// slow O(n^2) sort but should be good enough because user interface rarely has milion of items
var sortedList = Items.OrderBy(_sortByKey).ToList();
for (int i = 0; i < sortedList.Count; ++i)
{
var actualItemIndex = Items.IndexOf(sortedList[i]);
if (actualItemIndex != i)
Move(actualItemIndex, i);
}
}
}
..然后只需调用.Sort();
上述方法比重新创建整个项目源具有很大的优势 - 您的用户界面可以以相当方式对其做出反应(项目移动的动画而不是重新创建“闪烁”)