【问题标题】:Modifying an ObservableCollection using move()?使用 move() 修改 ObservableCollection?
【发布时间】:2012-06-08 15:18:31
【问题描述】:

我有一个关于修改绑定到 UI 中的 ListBox 的 ObservableCollection 中的各个项目的问题。

用户界面中的用户可以多选项目,然后将它们放在特定索引处以重新排序。

因此,如果我有项目 {0,1,2,3,4,5,6,7,8,9},用户可以选择项目 2、5、7(按此顺序)并选择删除它们在索引 3 处,因此集合现在变为,

{0,1,3, 2, 5, 7, 4, 8,9}

我现在的工作方式就像我控件上的 ondrop() 方法内部一样, 我会这样做:

foreach (Item item in draggedItems)
{
   int oldIndex = collection.IndexOf(item.DataContext as MyItemType);
   int newIndex = toDropIndex;

  if (newIndex == collection.Count)
  {
         newIndex--;
  }

  if (oldIndex != newIndex)
  {
     collection.Move(oldIndex, newIndex);                                     
  }

}

但问题是,如果我将项目放在开始拖动第一个项目的索引之前,则顺序会颠倒......所以集合变成了,

{0,1,3, 7, 5, 2, 4, 8,9}

如果我在索引 3 之后删除它可以正常工作,但如果我在 3 之前删除它,那么顺序就会颠倒。

现在,我可以进行简单的删除,然后在我想要的索引处插入所有项目,但“移动”对我来说具有将选择保留在 ui 中的优势(删除基本上取消选择列表中的项目..)....所以我需要使用 move 方法,

我上面的方法有什么问题以及如何解决? 谢谢!

【问题讨论】:

  • 从哪里获得 newDropIndex?
  • 我使用一种方法来获取用户当前所在的索引...所以如果用户将鼠标悬停在第 3 项上,则删除索引将为 3...

标签: c# wpf observablecollection


【解决方案1】:
foreach (Item item in draggedItems)
{
    int oldIndex = collection.IndexOf(item.DataContext as MyItemType);
    int newIndex = Math.Min(toDropIndex, (collection.Count - 1));

    if (oldIndex == newIndex)
        continue;

    collection.Move(oldIndex, newIndex);

    if (oldIndex > newIndex)
        toDropIndex++;
}

这应该可以帮助您。您需要增加 toDropIndex 以便将每个项目移动到最后一个项目的前面。否则,您只需将 2 移动到索引 3,然后将 5 移动到索引 3(将 2 推到索引 4),然后将 7 移动到索引 3(将 2 推到索引 5,将 5 推到索引 4)。这会将 2 放在索引 3 处,将 5 放在索引 4 处,将 7 放在索引 5 处。Math.Min() 函数将确保您永远不会超出范围。

【讨论】:

  • 那失败了,它在最后插入。
  • @user1202434:对不起,我更正了。应该是Math.Min(...) 而不是Math.Max(...)
  • 我想我同意,但不明白需要 (collection.Count - 1)。如果要添加项目,则 toDropIndex++ 不应超出范围。
  • 我给了你一个 +1。你能提供一个会发生这种情况的场景吗?
  • @Blam:当然,如果集合大小为 5 (0-4) 且 toDropIndex 为 4。在第一次迭代时,它将尝试将其移动到 4(后增量为 @987654326 @)。在第二次迭代中,toDropIndex 现在是 5,这已经超出了界限。 Math.Min(...) 保证它总是(最多)是最后一个索引。
【解决方案2】:

我觉得之前插入的时候应该用newIndex - 1,试试看能不能用。

LE:实际上,我认为是 +1

【讨论】:

    【解决方案3】:

    我推测这是因为您没有增加每个项目的“放置索引”,因此选择顺序(2、5、7)中的每个项目都被插入到索引“3”处,这会将它们呈现在倒序。

    添加;

    newIndex++;
    

    在循环的每次迭代中。

    或者,反向枚举您的集合;

    for (int i = draggedItems.Count; i >= 0; i--)
    {
        . . . 
    }
    

    【讨论】:

    • 如果我这样做,那么问题就反过来了,也就是说,如果我在拖动开始索引之后放置,则顺序是相反的,如果我之前放置它,那么它工作正常......
    • 也许发布完整的方法,包括你如何想出“拖动开始索引”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-15
    • 1970-01-01
    • 2011-09-10
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多