UWP/C#:ObservableCollection就地排序(不滚动) [英] UWP/C#: ObservableCollection sort in-place (w/o scrolling)

查看:90
本文介绍了UWP/C#:ObservableCollection就地排序(不滚动)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在UWP应用中,我正在尝试对绑定到ListViewObservableCollection进行排序-因此,collection.OrderBy(..)(创建新集合)不是一个选择.

In an UWP app I'm trying to sort an ObservableCollection that is bound to a ListView - therefore collection.OrderBy(..) (which creates a new collection) is not an option.

直到现在我都使用了这种扩展方法:

Until now I used this extension-method:

public static void Sort<TSource, TKey>(this 
ObservableCollection<TSource> source, Func<TSource, TKey> keySelector)
{
    List<TSource> sortedList = source.OrderBy(keySelector).ToList();
    source.Clear();
    foreach (var sortedItem in sortedList)
    {
        source.Add(sortedItem);
    }
}

不幸的是,由于source.Clear(),这种方式会重置当前的滚动偏移量",并且相应的ListView会一直滚动回到顶部,这是非常糟糕的用户体验.

Unfortunately this way the current 'scrolling-offset' is resetted due to source.Clear() and the corresponding ListView scrolls all the way back to the top - which is pretty bad user-experience.

有什么想法吗?

推荐答案

您可以尝试创建一个 temp 集合,其中包含原始集合中的所有项目,对其进行排序,然后遍历它的项目,并且仅对需要更新职位的项目进行重新排序.像这样-

What you can try is to create a temp collection that contains all the items from your original collection, sort it, then loop through its items and only re-order the ones of which position needs to be updated. Something like this -

public static void Sort<TSource, TKey>(this ObservableCollection<TSource> source, Func<TSource, TKey> keySelector)
{
    var sortedSource = source.OrderBy(keySelector).ToList();

    for (var i = 0; i < sortedSource.Count; i++)
    {
        var itemToSort = sortedSource[i];

        // If the item is already at the right position, leave it and continue.
        if (source.IndexOf(itemToSort) == i)
        {
            continue;
        }

        source.Remove(itemToSort);
        source.Insert(i, itemToSort);
    }
}

此外,您还希望ListView在制作动画时保持滚动偏移.可以通过设置-

Also, you will want the ListView to keep the scroll offset when items are animating. This can be done by setting -

<ItemsPanelTemplate>
    <ItemsStackPanel ItemsUpdatingScrollMode="KeepScrollOffset" />
</ItemsPanelTemplate>

我发现这个与UX相关的问题真的很有趣,我甚至最终为它创建了一个 demo项目 . :)下面的 gif 演示了最终结果.对我来说,从视觉上来说,它提供了更好的体验,即排序后哪些项已被重新定位或未重新排序.

I found this UX related question really interesting and I even ended up creating a little demo project for it. :) The gif below demostrates the end result. To me it provides a better experience as I know visually, what items are or aren't repositioned by the sorting.

这篇关于UWP/C#:ObservableCollection就地排序(不滚动)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆