web-dev-qa-db-ja.com

リストボックス内のアイテムを上下に移動する方法は?

ListBox1オブジェクトがあり、いくつかのアイテムが含まれています。選択したアイテムを上に移動するボタンと、選択したアイテムを下に移動するボタンがあります。 2つのボタンのコードはどうあるべきですか?

29
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);
}
74
Save

グーグルで検索してみましたか? リストボックスコントロールでアイテムを上下に移動する たとえば。

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..

DataSourceプロパティを使用してListBoxにデータバインドされたアイテムを移動できるように@Saveコードを変更しました。

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>に格納されているカスタムクラスです。

5
konrad

上記のDesolatorコードを変更して、コントロールをパラメーターとして渡す...再利用可能

    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

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

他のすべての答えは問題ありませんが、これも考慮する必要があります:)その考えはSwDevMan81からのものに近いですが、これは実際のコード(擬似ではない)であり、複数のアイテム(複数の選択アイテム)を移動できます下に移動するときに改善されました。

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

選択したアイテムのコレクションを取得し、次のように移動します。

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

DataSourceにバインドできるListBoxを処理する一般的な方法を探している人のために、通常のバインドされたListBoxを処理する Save's answer に基づく一般的な拡張機能があります。

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

}
0
The_Black_Smurf

これを複数の選択で使用します。また、インターリーブされた選択でも機能します。

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

上ボタンの場合:

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

下ボタンの場合:

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

選択したアイテムを移動するために、この関数を作成しました。

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