【问题标题】:programmatically move items in UWP ListView without refresh以编程方式在 UWP ListView 中移动项目而不刷新
【发布时间】:2018-05-02 10:49:12
【问题描述】:

下面的问题让我忙了很长时间,它似乎很基础,但它不起作用。归结为:

  • 在代码后面(ObservableCollection、ReactiveList 等)中有一个绑定到某个合适集合的 ListView
  • 我每 x 秒一次移动一个项目
  • 每次移动,所有项目都会刷新(至少看起来是这样的。在几秒钟内所有项目都会消失,然后以新的顺序重新出现)

必须有一种方法可以保留其他元素并“移动”被移动的项目。我什至不关心移动项目的精美翻译动画,我只想让其他元素留在屏幕上。 当然,我真正的用例不是随机移动项目,而是在后面的代码中对列表进行排序。但我将问题追溯到这个简单的案例。

拥有一个简单的 ListView 并绑定它,例如到 CodeBehind 中的 ObservableCollection,以下是我在项目周围移动的虚拟代码:

_timer = new Timer(async _ =>
{
    Random r = new Random();
    var randomIndex = r.Next(0, contactsCvsSource.Count - 1);

    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { contactsCvsSource.Move(randomIndex, 5); });
}
, null, 0, 1000);

【问题讨论】:

    标签: uwp


    【解决方案1】:

    每次移动时,所有项目都会刷新(至少看起来是这样的。在瞬间所有项目都会消失,然后以新顺序重新出现

    ObservableCollectionMove 方法用于提高 UI 刷新性能。调用Move方法时UI元素hash值不会改变,只是刷新ListView并没有重新创建。

    我只想让其他元素留在屏幕上。当然,我真正的用例不是随机移动项目,而是在后面的代码中对列表进行排序。

    根据您的要求,您可以通过InsertRemove 方法实现此功能。

    var _timer = new Timer(async _ =>
     {
         Random r = new Random();
         var randomIndex = r.Next(0, Items.Count - 1);
         await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
             Items.Insert(5,Items[randomIndex] );
             Items.RemoveAt(randomIndex);                   
         });
     }
     , null, 0, 1000);      
    

    【讨论】:

    • 嗨,最后我采用了一个解决方案,将我的语义移动转换为删除+添加,就像你建议的那样。然而,我仍然觉得奇怪的是,UWP ListView 没有将“移动”处理为“移动”(一个项目从这里移动到那里......)而是刷新了整个列表。
    猜你喜欢
    • 2019-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-08
    • 2010-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多