可以同时在列表框中向上移动多个项目,但不能向下移动
本文关键字:移动 项目 但不能 列表 | 更新日期: 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;
}
}
}
}
}