C# 对可观察的集合进行排序<;对象>;不';t更新用户界面
我正在构建一个Windows Phone 8.1(WinRt)应用程序 我有一个C# 对可观察的集合进行排序<;对象>;不';t更新用户界面,c#,linq,sorting,windows-runtime,C#,Linq,Sorting,Windows Runtime,我正在构建一个Windows Phone 8.1(WinRt)应用程序 我有一个可观察集合,我需要添加、修改和排序此集合的项目 当我将一个项目添加到此列表时,一切正常,如果我在列表中强制转换此对象的一个,并编辑该对象的属性,INotifyPropertyChanged负责更新ui 但是当我对列表排序时,UI不尊重列表的顺序 更新UI的唯一方法是使用Move(),但正如我发现的那样,这种方法需要大量的资源 我尝试过使用LINQ,但结果是列表是有序的,但UI中的元素保持相同的顺序 是否有其他方法对该
可观察集合
,我需要添加、修改和排序此集合的项目
当我将一个项目添加到此列表时,一切正常,如果我在列表中强制转换此对象的一个,并编辑该对象的属性,
INotifyPropertyChanged
负责更新ui
但是当我对列表排序时,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);
}
}
ActiveServices=ActiveServices.Where(x=>x是ActiveServiceControlData).OrderByDescending(x=>(x为ActiveServiceControlData).NotificationNumber).ToObservableCollection();
私有静态可观测集合活动服务;
公共可观测集合活动服务
{
获取{return activeServices;}
设置
{
主动服务=价值;
RaisePropertyChanged(()=>ActiveServices);
}
}
编辑
我的大问题是在ObservableCollection中有不同类型的对象,我使用此集合作为ListView的ItemsSource,并基于ObservableCollection中对象的类型使用ItemTemplateSelector,我只需要对特定类型的元素进行排序。对
ObservableCollection
进行排序的正确方法是扩展基本ObservableCollection
并使用内部CollectionChanged
事件
您当前的代码重新创建整个集合,这是低效的(并且您的用户界面可能会“闪烁”)
公共类SortableObservableCollection:ObservableCollection
{
私有只读功能;
公共SortableObservableCollection(Func sortByKey)
{
_sortByKey=sortByKey;
}
公共无效排序(){
//缓慢的O(n^2)排序,但应该足够好,因为用户界面很少有数以百万计的项目
var sortedList=Items.OrderBy(_sortByKey).ToList();
对于(int i=0;i
。。然后只需调用.Sort()
与重新创建整个项目源相比,上述方法有很大的优势-您的用户界面可以以非常好的方式对此做出反应(项目移动的动画而不是重新创建“闪烁”)
INotifyPropertyChanged
用于通知订阅者对象属性的更改。observedcollection
实现了INotifyCollectionChanged
,它通知订阅者集合内容的更改。LINQ方法通常没有副作用。向我们展示你试图做的事情(即提供代码),我们可以看看我们是否可以向你展示你做错了什么。你有一个非常不寻常的RaisePropertyChanged()方法,我可以看看它的实现吗?我使用的是mvvmlight,这就是为什么它看起来很不同。我没有看到任何让它不起作用的东西。可以稍微简化一下,但是。。。NPC应该传播并告诉UI重新读取集合。使用此代码,应用程序会由于集合中不同类型的对象而崩溃observablecollection@frenk91异常pleaseIt是由增量更新行为引起的xaml异常,而不是您的代码。但排序后,ui不会刷新。但正如我所解释的,move()方法是有效的fine@frenk91没有移动的排序?UI必须刷新-没有其他方法,您可能在UI中看不到这一点(毫无疑问,但也有可能),但会对UI性能产生严重影响(但在小列表的情况下,这是可以忽略的)
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);
}
}
}