对 ObservableCollection<object> 进行排序不会更新 UI

Sorting an ObservableCollection<object> doesn't update the UI

我正在开发一个 Windows Phone 8.1 (WinRt) 应用程序。

我有一个ObservableCollection<object>,我需要添加、修改和排序这个集合的项目。

当我向这个列表添加一个项目时一切正常,如果我在列表中投射这个对象之一并且我编辑对象的 属性 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);
    }
}

编辑

我的大问题是在 ObservableCollection 中有不同类型的对象,我将此集合用作 ListView 的 ItemsSource,并根据 ObservableCollection 中对象的类型使用 ItemTemplateSelector,我只需要排序特定类型的元素。

排序 ObservableCollection 的正确方法是扩展基础 ObservableCollection 并利用内部 CollectionChanged 事件。

您当前的代码重新创建了效率低下的整个集合(并且您的用户界面可能 "blink")。

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();

上述方法比重新创建整个项目源有很大优势 - 您的用户界面可以以漂亮的方式对此做出反应(项目移动的动画而不是重新创建 "blink")