J'ai un objet listBox1 et il contient quelques éléments. J'ai un bouton pour déplacer l'élément sélectionné vers le haut et un autre pour déplacer l'élément sélectionné vers le bas. Quel devrait être le code pour les deux boutons?
private 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 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);
}
Avez-vous essayé de chercher dans google? Déplacer les éléments vers le haut/bas dans le contrôle de zone de liste par exemple.
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;
}
}
}
}
}
Code @Save modifié pour permettre le déplacement d'éléments liés à un ListBox à l'aide de la propriété DataSource.
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);
}
Où UnifyCamera
est ma classe personnalisée qui est stockée dans une liste inputData.Cameras
qui retourne un List<UnifyCamera>
.
Code Desolator modifié ci-dessus pour passer le contrôle en tant que paramètre ... réutilisable
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);
}
La réponse de Vexe a fonctionné au mieux pour moi, mais j'ai dû la modifier pour résoudre quelques problèmes. Cette solution mettra en évidence le bon objet si le même objet est plusieurs fois dans la zone de liste. En outre, cette solution empêche les objets à sélections multiples de basculer quand ils atteignent le haut ou le bas de la zone de liste et que le bouton continue d’être appuyé plusieurs fois.
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();
}
Toutes les autres réponses sont correctes, mais vous devriez également considérer celle-ci:) L’idée en est proche de celle de SwDevMan81 mais c’est du code réel (pas pseudo) Et vous pouvez déplacer plusieurs éléments (plusieurs éléments sélectionnés) et avec une amélioration en descendant.
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();
}
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);
}
}
// Options is a list box
private void MoveUpButton_Click(object sender,EventArgs e) {
int index = Options.SelectedIndex;
if (index <= 0) return;
string item = (string)Options.Items[index - 1];
Options.Items.RemoveAt(index - 1);
Options.Items.Insert(index,item);
selectedIndexChanged(null,null);
}
private void MoveDnButton_Click(object sender,EventArgs e) {
int index = Options.SelectedIndex;
if (index + 1 >= Options.Items.Count) return;
string item = (string)Options.Items[index];
Options.Items.RemoveAt(index);
Options.Items.Insert(index + 1,item);
Options.SelectedIndex = index + 1;
}
// sent when user makes a selection or when he moves an item up or down
private void selectedIndexChanged(object sender,EventArgs e) {
int index = Selected.SelectedIndex;
MoveUpButton.Enabled = index > 0;
MoveDnButton.Enabled = index + 1 < Selected.Items.Count;
}
private void btnUp_Click(object sender, System.EventArgs e)
{
if (this.lbItems.SelectedIndex == -1 || this.lbItems.SelectedIndex == 0)
return;
Object select, previous, temp;
select = lbItems.Items[lbItems.SelectedIndex];
previous = lbItems.Items[lbItems.SelectedIndex-1];
temp = select;
select = previous;
previous = temp;
lbItems.Items[lbItems.SelectedIndex] = select;
lbItems.Items[lbItems.SelectedIndex-1] = previous;
lbItems.SelectedIndex--;
}
private void btnDown_Click(object sender, System.EventArgs e)
{
if (this.lbItems.SelectedIndex == -1 || this.lbItems.SelectedIndex == lbItems.Items.Count-1)
return;
Object select, next, temp;
select = lbItems.Items[lbItems.SelectedIndex];
next = lbItems.Items[lbItems.SelectedIndex+1];
temp = select;
select = next;
next = temp;
lbItems.Items[lbItems.SelectedIndex] = select;
lbItems.Items[lbItems.SelectedIndex+1] = next;
lbItems.SelectedIndex++;
}
Je l’utilise avec plusieurs sélections . Il fonctionne également avec des sélections entrelacées.
private void Order_buttons_Click(object sender, EventArgs e)
{
//If noselection return
if (Layouts_listBox.SelectedItems.Count == 0) return;
//Determines wether up or down
int movement = (sender as Button) == Order_Upbutton? - 1 : 1;
//creates a dictionary associating the original Index (ListBox) to the text
Dictionary<int, string> Items = new Dictionary<int, string>();
//Also creates a list with the Index for sorting
List<int> DesiredOrder = new List<int>();
//Cycle through the selection and fill both the list and dictionary
ListBox.SelectedObjectCollection NN = Layouts_listBox.SelectedItems;
foreach (object n in NN)
{
DesiredOrder.Add(Layouts_listBox.Items.IndexOf(n));
Items.Add(Layouts_listBox.Items.IndexOf(n), (string)n);
}
//Sort the List according to the desired button (Up or Down)
DesiredOrder.Sort();
if ((sender as Button) != Order_Upbutton) DesiredOrder.Reverse();
//I'm using this ErrorHandling but thats up to you
try
{
//Call the MoveItem (Credits to Save) according to the sorted order
foreach (int n in DesiredOrder) MoveItem(movement, Items[n]);
}
catch (Exception)
{
SystemSounds.Asterisk.Play();
}
}
public void MoveItem(int direction, string Selected)
{
// Checking selected item
if (!Layouts_listBox.Items.Contains(Selected) || Layouts_listBox.Items.IndexOf(Selected) < 0)
throw new System.Exception(); // No selected item - Cancel entire Func
// Calculate new index using move direction
int newIndex = Layouts_listBox.Items.IndexOf(Selected) + direction;
// Checking bounds of the range
if (newIndex < 0 || newIndex >= Layouts_listBox.Items.Count)
throw new System.Exception(); // Index out of range - Cancel entire Func
object selected = Layouts_listBox.Items[Layouts_listBox.Items.IndexOf(Selected)];
// Removing removable element
Layouts_listBox.Items.Remove(selected);
// Insert it in new position
Layouts_listBox.Items.Insert(newIndex, selected);
// Restore selection
Layouts_listBox.SetSelected(newIndex, true);
}
Obtenez une collection des éléments sélectionnés, puis déplacez-les comme suit:
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);
}
}
}
Pour le bouton haut:
private void UpBottom_Click(object sender, EventArgs e)
{
//this.Options is ListBox
if (this.Options.SelectedIndex == -1 ||
this.Options.SelectedIndex == 0)
return;
string item, aboveItem;
int itemIndex, aboveItemIndex;
itemIndex = this.Options.SelectedIndex;
aboveItemIndex = this.Options.SelectedIndex - 1;
item = (string)this.Options.Items[itemIndex];
aboveItem = (string)this.Options.Items[aboveItemIndex];
this.Options.Items.RemoveAt(aboveItemIndex);
this.Options.Items.Insert(itemIndex, aboveItem);
}
Pour le bouton bas:
private void DownButton_Click(object sender, EventArgs e)
{
//this.Options is ListBox
if (this.Options.SelectedIndex == -1 ||
this.Options.SelectedIndex >= this.Options.Items.Count)
return;
string item, belowItem;
int itemIndex, belowItemIndex;
itemIndex = this.Options.SelectedIndex;
belowItemIndex = this.Options.SelectedIndex + 1;
if (belowItemIndex >= this.Options.Items.Count)
return;
item = (string)this.Options.Items[itemIndex];
belowItem = (string)this.Options.Items[belowItemIndex];
this.Options.Items.RemoveAt(itemIndex);
this.Options.Items.Insert(belowItemIndex, item);
this.Options.SelectedIndex = belowItemIndex;
}
J'ai écrit cette fonction pour déplacer les éléments sélectionnés:
using System.Collections;
using System.Collections.Generic;
private void MoveListboxItems(int step, ListBox lb) {
/* 'step' should be:
* -1 for moving selected items up
* 1 for moving selected items down
* 'lb' is your ListBox
* see examples how to call below this function
*/
try {
// do only something when really an item is selected
if (lb.SelectedIndex > -1) {
// get some needed values - they change while we manipulate the listbox
// but we need them as they was original
IList SelectedItems = lb.SelectedItems;
IList SelectedIndices = lb.SelectedIndices;
// set some default values
int selIndex = -1;
int newIndex = -1;
int selCount = SelectedItems.Count;
int lc = 0;
int mc = 0;
string moveOldValue = string.Empty;
string selectedItemValue = string.Empty;
if (step == 1) {
mc = selCount - 1;
} else {
mc = lc;
}
// enter the loop through the selected items
while (lc < selCount) {
selectedItemValue = string.Empty;
moveOldValue = string.Empty;
try {
// get the item that should get moved
selectedItemValue = SelectedItems[mc].ToString();
selIndex = Convert.ToInt32(SelectedIndices[mc]);
} catch {
selIndex = -1;
}
// gen index for new place
newIndex = selIndex + step;
try {
// get the old value from the place where the item get moved
moveOldValue = lb.Items[newIndex].ToString();
} catch { /* do nothing */ }
try {
if (!String.IsNullOrEmpty(selectedItemValue) && !String.IsNullOrEmpty(moveOldValue) && selIndex != -1 && newIndex != -1 && !lb.SelectedIndices.Contains(newIndex)) {
// move selected item
lb.Items.RemoveAt(newIndex);
lb.Items.Insert(newIndex, selectedItemValue);
// write old value back to the old place from selected item
lb.Items.RemoveAt(selIndex);
lb.Items.Insert(selIndex, moveOldValue);
// hold the moved item selected
lb.SetSelected(newIndex, true);
}
} catch { /* do nothing */ }
lc++;
if (step == 1) {
mc -= step;
} else {
mc = lc;
}
}
}
} catch { /* do nothing */ };
}
// examples how i call the function above
void BtnLbUp_Click(object sender, EventArgs e) {
MoveListboxItems(-1, this.lbMyList);
}
void BtnLbDown_Click(object sender, EventArgs e) {
MoveListboxItems(1, this.lbMyList);
}