Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对可观察的集合进行排序<;对象>;不';t更新用户界面_C#_Linq_Sorting_Windows Runtime - Fatal编程技术网

C# 对可观察的集合进行排序<;对象>;不';t更新用户界面

C# 对可观察的集合进行排序<;对象>;不';t更新用户界面,c#,linq,sorting,windows-runtime,C#,Linq,Sorting,Windows Runtime,我正在构建一个Windows Phone 8.1(WinRt)应用程序 我有一个可观察集合,我需要添加、修改和排序此集合的项目 当我将一个项目添加到此列表时,一切正常,如果我在列表中强制转换此对象的一个,并编辑该对象的属性,INotifyPropertyChanged负责更新ui 但是当我对列表排序时,UI不尊重列表的顺序 更新UI的唯一方法是使用Move(),但正如我发现的那样,这种方法需要大量的资源 我尝试过使用LINQ,但结果是列表是有序的,但UI中的元素保持相同的顺序 是否有其他方法对该

我正在构建一个Windows Phone 8.1(WinRt)应用程序

我有一个
可观察集合
,我需要添加、修改和排序此集合的项目


当我将一个项目添加到此列表时,一切正常,如果我在列表中强制转换此对象的一个,并编辑该对象的属性,
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);
        }

    }
}