web-dev-qa-db-fra.com

Comment déplacer un élément dans la liste déroulante?

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?

25
user586399
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);
   }
}
17
SwDevMan81
 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);
}
67
Save

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;
                  }

              }
         }
     }
}
6
CD..

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);
        }

UnifyCamera est ma classe personnalisée qui est stockée dans une liste inputData.Cameras qui retourne un List<UnifyCamera>

4
konrad

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);
    }
4
Habesha

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();
    }
2
Miebster

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();
}
2
vexe
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);
        }
    }
2
Mnyikka
// 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;
    }
1
SaulN
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++;
}
1
harsha

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);
    }
  }
}
0
RooiWillie

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;
    }
0
Yasser-Taherkhani

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);
}
0
anoCoder