我有一个listBox1对象,其中包含一些项目。我有一个按钮可以将选定的项目向上移动,另一个按钮可以将选定的项目向下移动。这两个按钮的代码应该是什么?
public void MoveUp()
{
MoveItem(-1);
}
public void MoveDown()
{
MoveItem(1);
}
public void MoveItem(int direction)
{
// Checking selected item
if (listBox1.SelectedItem == null || listBox1.SelectedIndex < 0)
return; // No selected item - nothing to do
// Calculate new index using move direction
int newIndex = listBox1.SelectedIndex + direction;
// Checking bounds of the range
if (newIndex < 0 || newIndex >= listBox1.Items.Count)
return; // Index out of range - nothing to do
object selected = listBox1.SelectedItem;
// Removing removable element
listBox1.Items.Remove(selected);
// Insert it in new position
listBox1.Items.Insert(newIndex, selected);
// Restore selection
listBox1.SetSelected(newIndex, true);
}
更新于2020-03-24: 扩展类可简单重用,同时还支持CheckedListBox(如果您不需要CheckedListBox,请删除相应的代码行)。感谢@dognose和@Chad
public static class ListBoxExtension
{
public static void MoveSelectedItemUp(this ListBox listBox)
{
_MoveSelectedItem(listBox, -1);
}
public static void MoveSelectedItemDown(this ListBox listBox)
{
_MoveSelectedItem(listBox, 1);
}
static void _MoveSelectedItem(ListBox listBox, int direction)
{
// Checking selected item
if (listBox.SelectedItem == null || listBox.SelectedIndex < 0)
return; // No selected item - nothing to do
// Calculate new index using move direction
int newIndex = listBox.SelectedIndex + direction;
// Checking bounds of the range
if (newIndex < 0 || newIndex >= listBox.Items.Count)
return; // Index out of range - nothing to do
object selected = listBox.SelectedItem;
// Save checked state if it is applicable
var checkedListBox = listBox as CheckedListBox;
var checkState = CheckState.Unchecked;
if (checkedListBox != null)
checkState = checkedListBox.GetItemCheckState(checkedListBox.SelectedIndex);
// Removing removable element
listBox.Items.Remove(selected);
// Insert it in new position
listBox.Items.Insert(newIndex, selected);
// Restore selection
listBox.SetSelected(newIndex, true);
// Restore checked state if it is applicable
if (checkedListBox != null)
checkedListBox.SetItemCheckState(newIndex, checkState);
}
}
ListBox
参数,因此只需将其传递给函数即可在任何 ListBox
上使用该函数。 - ChadChckedListBox
,您可能还想添加以下两行代码:在移动之前添加 CheckState checkState = checkedListBox1.GetItemCheckState(checkedListBox1.SelectedIndex);
,并在末尾添加以下一行代码:checkedListBox1.SetItemCheckState(newIndex, checkState);
- dognoseprivate void UpClick()
{
// only if the first item isn't the current one
if(listBox1.ListIndex > 0)
{
// add a duplicate item up in the listbox
listBox1.AddItem(listBox1.Text, listBox1.ListIndex - 1);
// make it the current item
listBox1.ListIndex = (listBox1.ListIndex - 2);
// delete the old occurrence of this item
listBox1.RemoveItem(listBox1.ListIndex + 2);
}
}
private void DownClick()
{
// only if the last item isn't the current one
if((listBox1.ListIndex != -1) && (listBox1.ListIndex < listBox1.ListCount - 1))
{
// add a duplicate item down in the listbox
listBox1.AddItem(listBox1.Text, listBox1.ListIndex + 2);
// make it the current item
listBox1.ListIndex = listBox1.ListIndex + 2;
// delete the old occurrence of this item
listBox1.RemoveItem(listBox1.ListIndex - 2);
}
}
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;
}
}
}
}
}
修改了@Save代码,以允许使用DataSource属性将数据绑定到ListBox的项进行移动。
public void MoveItem(int direction)
{
// Checking selected item
if (listBox1.SelectedItem == null || listBox1.SelectedIndex < 0)
return; // No selected item - nothing to do
// Calculate new index using move direction
int newIndex = listBox1.SelectedIndex + direction;
// Checking bounds of the range
if (newIndex < 0 || newIndex >= listBox1.Items.Count)
return; // Index out of range - nothing to do
UnifyCamera selected = listBox1.SelectedItem as UnifyCamera;
// modify the data source list
inputData.Cameras.RemoveAt(listBox1.SelectedIndex);
inputData.Cameras.Insert(newIndex, selected);
// re-bind your data source
((ListBox)listBox1).DataSource = null;
((ListBox)listBox1).DataSource = this.inputData.Cameras;
((ListBox)listBox1).DisplayMember = "Name";
// Restore selection
listBox1.SetSelected(newIndex, true);
}
这里的UnifyCamera
是我的自定义类,存储在列表inputData.Cameras
中,该列表返回一个List<UnifyCamera>
。
将上述修改后的荒芜者代码作为参数传递控制...可重复使用
private void MoveUp()
{
MoveItem(-1,listBox1);
}
private void MoveDown()
{
MoveItem(1,listBox1);
}
public void MoveItem(int direction,ListBox listBox)
{
// Checking selected item
if (listBox.SelectedItem == null || listBox.SelectedIndex < 0)
return; // No selected item - nothing to do
// Calculate new index using move direction
int newIndex = listBox.SelectedIndex + direction;
// Checking bounds of the range
if (newIndex < 0 || newIndex >= listBox.Items.Count)
return; // Index out of range - nothing to do
object selected = listBox.SelectedItem;
// Removing removable element
listBox.Items.Remove(selected);
// Insert it in new position
listBox.Items.Insert(newIndex, selected);
// Restore selection
listBox.SetSelected(newIndex, true);
}
Vexe的回答对我来说运行得最好,但是我不得不修改它来解决一些问题。该解决方案将在列表框中多次出现相同对象时突出显示正确的对象。此外,该解决方案防止多选对象在击中列表框的顶部或底部并且按钮被多次按下时翻转。
private void btnMoveUp_Click(object sender, EventArgs e)
{
// find the lowest index of non selected items
int lowestIndexNotSelected = listBox.Items.Count - 1;
for (int i = listBox.Items.Count - 1; i >= 0; i--)
{
if (!listBox.SelectedIndices.Contains(i))
{
lowestIndexNotSelected = i;
}
}
listBox.BeginUpdate();
int numberOfSelectedItems = listBox.SelectedItems.Count;
for (int i = 0; i < numberOfSelectedItems; i++)
{
// only if it's not a lower inde than the lowest non selected index
if (listBox.SelectedIndices[i] > lowestIndexNotSelected)
{
// the index of the item above the item that we wanna move up
int indexToInsertIn = listBox.SelectedIndices[i] - 1;
// insert UP the item that we want to move up
listBox.Items.Insert(indexToInsertIn, listBox.SelectedItems[i]);
// removing it from its old place
listBox.Items.RemoveAt(indexToInsertIn + 2);
// highlighting it in its new place (by index, to prevent highlighting wrong instance)
listBox.SelectedIndex = indexToInsertIn;
}
}
listBox.EndUpdate();
}
private void btnMoveDown_Click(object sender, EventArgs e)
{
// find the highest index of non selected items
int highestIndexNonSelected = 0;
for (int i = 0; i < listBox.Items.Count; i++)
{
if (!listBox.SelectedIndices.Contains(i))
{
highestIndexNonSelected = i;
}
}
listBox.BeginUpdate();
int numberOfSelectedItems = listBox.SelectedItems.Count;
// when going down, instead of moving through the selected items from top to bottom
// we'll go from bottom to top, it's easier to handle this way.
for (int i = numberOfSelectedItems - 1; i >= 0; i--)
{
// only if it's not a higher index than the highest index not selected
if (listBox.SelectedIndices[i] < highestIndexNonSelected)
{
// the index of the item that is currently below the selected item
int indexToInsertIn = listBox.SelectedIndices[i] + 2;
// insert DOWN the item that we want to move down
listBox.Items.Insert(indexToInsertIn, listBox.SelectedItems[i]);
// removing it from its old place
listBox.Items.RemoveAt(indexToInsertIn - 2);
// highlighting it in its new place (by index, to prevent highlighting wrong instance)
listBox.SelectedIndex = indexToInsertIn - 1;
}
}
listBox.EndUpdate();
}
public static void MoveUpOrDownSelectedItem(ListBox LisBox, bool MoveUp)
{
if (LisBox.SelectedIndex > 0 && MoveUp)
{
// add a duplicate item up in the listbox
LisBox.Items.Insert(LisBox.SelectedIndex - 1, LisBox.SelectedItem);
// make it the current item
LisBox.SelectedIndex = (LisBox.SelectedIndex - 2);
// delete the old occurrence of this item
LisBox.Items.RemoveAt(LisBox.SelectedIndex + 2);
}
if ((LisBox.SelectedIndex != -1) && (LisBox.SelectedIndex < LisBox.Items.Count- 1) && MoveUp == false)
{
// add a duplicate item down in the listbox
int IndexToRemove = LisBox.SelectedIndex;
LisBox.Items.Insert(LisBox.SelectedIndex + 2, LisBox.SelectedItem);
// make it the current item
LisBox.SelectedIndex = (LisBox.SelectedIndex + 2);
// delete the old occurrence of this item
LisBox.Items.RemoveAt(IndexToRemove);
}
}
private void MoveUp_listBox_button_Click(object sender, EventArgs e)
{
listBox.BeginUpdate();
int numberOfSelectedItems = listBox.SelectedItems.Count;
for (int i = 0; i < numberOfSelectedItems; i++)
{
// only if it's not the first item
if (listBox.SelectedIndices[i] > 0)
{
// the index of the item above the item that we wanna move up
int indexToInsertIn = listBox.SelectedIndices[i] - 1;
// insert UP the item that we want to move up
listBox.Items.Insert(indexToInsertIn, listBox.SelectedItems[i]);
// removing it from its old place
listBox.Items.RemoveAt(indexToInsertIn + 2);
// highlighting it in its new place
listBox.SelectedItem = listBox.Items[indexToInsertIn];
}
}
listBox.EndUpdate();
}
private void MoveDown_listBox_button_Click(object sender, EventArgs e)
{
listBox.BeginUpdate();
int numberOfSelectedItems = listBox.SelectedItems.Count;
// when going down, instead of moving through the selected items from top to bottom
// we'll go from bottom to top, it's easier to handle this way.
for (int i = numberOfSelectedItems-1; i >= 0; i--)
{
// only if it's not the last item
if (listBox.SelectedIndices[i] < listBox.Items.Count - 1)
{
// the index of the item that is currently below the selected item
int indexToInsertIn = listBox.SelectedIndices[i] + 2;
// insert DOWN the item that we want to move down
listBox.Items.Insert(indexToInsertIn, listBox.SelectedItems[i]);
// removing it from its old place
listBox.Items.RemoveAt(indexToInsertIn - 2);
// highlighting it in its new place
listBox.SelectedItem = listBox.Items[indexToInsertIn - 1];
}
}
listBox.EndUpdate();
}
private void btnMoveUp_Click(object sender, EventArgs e)
{
HashSet<KeyValuePair<int, object>> ItemsToMove = new HashSet<KeyValuePair<int, object>>();
foreach (object o in lstMyListView.SelectedItems)
ItemsToMove.Add(new KeyValuePair<int, object>(lstMyListView.Items.IndexOf(o), o));
foreach (KeyValuePair<int, object> kvp in ItemsToMove)
{
if (kvp.Key > 0) // check if its the first item before moving
{
lstMyListView.Items.Remove(kvp.Value);
lstMyListView.Items.Insert(kvp.Key - 1, kvp.Value);
}
}
}
private void btnMoveDown_Click(object sender, EventArgs e)
{
HashSet<KeyValuePair<int, object>> ItemsToMove = new HashSet<KeyValuePair<int, object>>();
foreach (object o in lstMyListView.SelectedItems)
ItemsToMove.Add(new KeyValuePair<int, object>(lstMyListView.Items.IndexOf(o), o));
foreach (KeyValuePair<int, object> kvp in ItemsToMove)
{
if (kvp.Key < lstMyListView.Items.Count - 1) // check if its the last item before moving
{
lstMyListView.Items.Remove(kvp.Value);
lstMyListView.Items.Insert(kvp.Key + 1, kvp.Value);
}
}
}
对于那些正在寻找一种通用的方法来处理ListBox,该方法可以绑定到数据源,这里提供了一个基于Save's answer的通用扩展程序,可以处理常规和绑定的ListBox。
public static void MoveUp(this ListBox listBox)
{
listBox.MoveItem(-1);
}
public static void MoveDown(this ListBox listBox)
{
listBox.MoveItem(1);
}
public static void MoveItem(this ListBox listBox, int direction)
{
// Checking selected item
if (listBox.SelectedItem == null || listBox.SelectedIndex < 0)
return; // No selected item - nothing to do
// Calculate new index using move direction
int newIndex = listBox.SelectedIndex + direction;
// Checking bounds of the range
if (newIndex < 0 || newIndex >= listBox.Items.Count)
return; // Index out of range - nothing to do
//Find our if we're dealing with a BindingSource
bool isBindingSource = listBox.DataSource is BindingSource;
//Get the list
System.Collections.IList list = isBindingSource ? ((BindingSource)listBox.DataSource).List : listBox.Items;
object selected = listBox.SelectedItem;
// Removing removable element
list.Remove(selected);
// Insert it in new position
list.Insert(newIndex, selected);
// Restore selection
listBox.SetSelected(newIndex, true);
if (isBindingSource)
{
//Reset the binding if needed
((BindingSource)listBox.DataSource).ResetBindings(false);
}
}