可以同时在列表框中向上移动多个项目,但不能向下移动

本文关键字:移动 项目 但不能 列表 | 更新日期: 2023-09-27 18:04:35

我有一个奇怪的bug,我很难弄清楚。

如果我在ListBox中选择多个项目,然后选择向上箭头,所有的项目就会完美地向上移动一个空格,就好像它们是一个单元一样。但是,当单击向下箭头将列表中的每个项目向下移动一个位置时,就不会发生这种情况。

相反,如果我选择偶数个项目,然后单击向下箭头,所有项目都不会移动,如果我选择奇数个项目,然后单击向下箭头,只有底部的项目向下移动一个空格,而所有其他项目都保持不变。

有人知道为什么会发生这种情况吗?

下面是我用来处理物品移动的代码:

private void MoveItemInSelectedItemsListBox(object sender)
{
  if (selectedItemsListBox.SelectedItems.Count > 0)
  {
    // Build list of items to be moved
    List<object> listOfItemsToBeMoved = new List<object>();
    for (int i = 0; i < selectedItemsListBox.SelectedItems.Count; i++)
    {
      listOfItemsToBeMoved.Add(selectedItemsListBox.SelectedItems[i]);
    }
    for (int k = 0; k < listOfItemsToBeMoved.Count; k++)
    {
      var selectedItem = listOfItemsToBeMoved[k];
      int selectedItemIndex = selectedItemsListBox.Items.IndexOf(selectedItem);
      int numberOfItemsInList = selectedItemsListBox.Items.Count;
      // If up arrow was clicked
      if (sender.ToString().Contains("▲"))
      {
        if (selectedItemIndex == 0)
        {
          selectedItemsListBox.Items.Remove(selectedItem);
          selectedItemsListBox.Items.Insert(numberOfItemsInList - 1, selectedItem);
          selectedItemsListBox.SetSelected(numberOfItemsInList - 1, true);
        }
        else
        {
          selectedItemsListBox.Items.Remove(selectedItem);
          selectedItemsListBox.Items.Insert(selectedItemIndex - 1, selectedItem);
          selectedItemsListBox.SetSelected(selectedItemIndex - 1, true);
        }
      }
      // If down arrow was clicked
      else if (sender.ToString().Contains("▼"))
      {
        if (selectedItemIndex == numberOfItemsInList - 1)
        {
          selectedItemsListBox.Items.Remove(selectedItem);
          selectedItemsListBox.Items.Insert(0, selectedItem);
          selectedItemsListBox.SetSelected(0, true);
        }
        else
        {
          selectedItemsListBox.Items.Remove(selectedItem);
          selectedItemsListBox.Items.Insert(selectedItemIndex + 1, selectedItem);
          selectedItemsListBox.SetSelected(selectedItemIndex + 1, true);
        }
      }
    }
  }
}

可以同时在列表框中向上移动多个项目,但不能向下移动

这是for循环方向的问题:本质上,当向下移动项目时,如果你实际上是在通过列表向上移动,同时检查项目向下移动,你最终会出现重叠和其他奇怪的事情。我的解决方案是,如果你要向下移动项目,就对项目做一个循环:

if (selectedItemsListBox.SelectedItems.Count > 0)
{
    List<object> itemsToMove = (from object item in selectedItemsListBox.SelectedItems select item).ToList();
    int numItems = selectedItemsListBox.Items.Count;
    // If up arrow was clicked
    if (sender.ToString().Contains("▲"))
    {
        for (int i = 0; i < itemsToMove.Count; i++)
        {
            var selectedItem = itemsToMove[i];
            int oldIndex = selectedItemsListBox.Items.IndexOf(selectedItem);
            int newIndex = oldIndex == 0 ? numItems - 1 : oldIndex - 1;
            selectedItemsListBox.Items.Remove(selectedItem);
            selectedItemsListBox.Items.Insert(newIndex, selectedItem);
            selectedItemsListBox.SetSelected(newIndex, true);
        }
    }
    // If down arrow was clicked
    else if (sender.ToString().Contains("▼"))
    {
        for (int i = itemsToMove.Count - 1; i >= 0; i--)
        {
            var selectedItem = itemsToMove[i];
            int oldIndex = selectedItemsListBox.Items.IndexOf(selectedItem);
            int newIndex = oldIndex == numItems - 1 ? 0 : oldIndex + 1;
            selectedItemsListBox.Items.Remove(selectedItem);
            selectedItemsListBox.Items.Insert(newIndex, selectedItem);
            selectedItemsListBox.SetSelected(newIndex, true);
        }
    }
}

(我还采取了一些自由,使一些代码更小,例如通过改变一些变量名。)

发现这个例子可能是一个更好的、清晰的、可重用的选项。

public class SmartListBox : ListBox
{
    //Moves the selected items up one level
    public MoveUp()
    {
        for(int i = 0; i < Items.Count; i++)
        {
            if (Items[i].Selected)//identify the selected item
            {
                //swap with the top item(move up)
                if (i > 0 && !Items[i - 1].Selected)
                {
                     ListItem bottom = Items[i];
                     Items.Remove(bottom);
                     Items.Insert(i - 1, bottom);
                     Items[i - 1].Selected = true;
                 }
              }
          }
     }
     //Moves the selected items one level down
     public MoveDown()
     {
         int startindex = Items.Count -1;
         for (int i = startindex; i > -1; i--)
         {
              if (Items[i].Selected)//identify the selected item
              { 
                  //swap with the lower item(move down)
                  if (i < startindex && !Items[i + 1].Selected)
                  {
                       ListItem bottom = Items[i];
                       Items.Remove(bottom);
                       Items.Insert(i + 1, bottom);
                       Items[i + 1].Selected = true;
                  }
              }
         }
     }
}