10

たくさんの値が入ったリストボックスがあります。UPボタンとDOWNボタンもあります。これらのボタンを使用して、リストボックスで選択した項目を上下に移動したいと思います。私はこれを行うのに問題があります。

これまでの私のコードは次のとおりです。

    private void btnDataUp_Click(object sender, RoutedEventArgs e)
    {

        int selectedIndex = listBoxDatasetValues.SelectedIndex; //get the selected item in the data list

        if (selectedIndex != -1 && selectedIndex != 0) //if the selected item is selected and not at the top of the list
        {
            //swap items here
            listBoxDatasetValues.SelectedIndex = selectedIndex - 1; //keep the item selected
        }


    }

値を入れ替える方法がわかりません!どんな助けでも大歓迎です!

4

8 に答える 8

26

ItemsSourceを使用してObservableCollectionにバインドすることでリストボックスにデータを入力したため、リストボックスのItemsプロパティを変更することはできません。

ItemsSourceは、Itemsコレクションが空の場合にのみ設定でき、ItemsSourceがnullの場合にのみ変更できます。

そうしないと、「ItemsSourceの使用中は操作が無効です...」というエラーが発生します。

必要なのは、基になるコレクションを変更することです。これはObservableCollectionであるため、ListBoxは変更を反映します。

次のコードは、コレクション内のアイテムを交換することにより、アイテムを上下に移動する方法を示しています。

対応するXAMLには、lbItemsというリストボックスと、イベントハンドラーを接続する2つのボタンが含まれています。

public partial class MainWindow : Window
{
    private ObservableCollection<string> ListItems = new ObservableCollection<string>  
    { 
        "Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6"
    };

    public MainWindow()
    {
        InitializeComponent();
        lbItems.ItemsSource = this.ListItems;
    }

    private void up_click(object sender, RoutedEventArgs e)
    {
        var selectedIndex = this.lbItems.SelectedIndex;

        if (selectedIndex > 0)
        {
            var itemToMoveUp = this.ListItems[selectedIndex];
            this.ListItems.RemoveAt(selectedIndex);
            this.ListItems.Insert(selectedIndex - 1, itemToMoveUp);
            this.lbItems.SelectedIndex = selectedIndex - 1;
        }
    }

    private void down_click(object sender, RoutedEventArgs e)
    {
        var selectedIndex = this.lbItems.SelectedIndex;

        if (selectedIndex + 1 < this.ListItems.Count)
        {
            var itemToMoveDown = this.ListItems[selectedIndex];
            this.ListItems.RemoveAt(selectedIndex);
            this.ListItems.Insert(selectedIndex + 1, itemToMoveDown);
            this.lbItems.SelectedIndex = selectedIndex + 1;
        }
    }
}
于 2012-09-22T10:08:29.640 に答える
10

私はこれのためにいくつかの拡張メソッドを作ります:

    public static void MoveItemUp<T>(this ObservableCollection<T> baseCollection, int selectedIndex)
    {
        //# Check if move is possible
        if (selectedIndex <= 0)
            return;

        //# Move-Item
        baseCollection.Move(selectedIndex - 1, selectedIndex);
    }

    public static void MoveItemDown<T>(this ObservableCollection<T> baseCollection, int selectedIndex)
    {
        //# Check if move is possible
        if (selectedIndex < 0 || selectedIndex + 1 >= baseCollection.Count)
            return;

        //# Move-Item
        baseCollection.Move(selectedIndex + 1, selectedIndex);
    }

    public static void MoveItemDown<T>(this ObservableCollection<T> baseCollection, T selectedItem)
    {
        //# MoveDown based on Item
        baseCollection.MoveItemDown(baseCollection.IndexOf(selectedItem));
    }

    public static void MoveItemUp<T>(this ObservableCollection<T> baseCollection, T selectedItem)
    {
        //# MoveUp based on Item
        baseCollection.MoveItemUp(baseCollection.IndexOf(selectedItem));
    }

このためにリストボックスを知る必要はありません。

于 2014-01-24T10:09:06.730 に答える
5

これはこれを行う最も簡単な方法であり、すべての適切なイベントを発生させるため、XAMLについて心配する必要はありません。ObservableCollectionには、という優れたメソッドがあります

MoveItem(previousIndex, newIndex)

DataItemListという名前のObservableCollectionがあるとします。

public void MoveUp()
{
  var currentIndex = DataItemList.SelectedIndex;

  //Index of the selected item
  if (currentIndex > 0)
  {
    int upIndex = currentIndex - 1;

    //move the items
    DataItemList.MoveItem(upIndex,currentIndex);         
  }
}

ダウンの場合、前のアイテムのインデックスを取得します。

そのような単純な!

于 2013-01-25T21:00:52.523 に答える
3

コメントを追加したかったのですが、評判が3つしかないので追加できません:/

Peter Hansenのソリューションは素晴らしいですが、選択された要素がない場合、down_clickはArgumentOutOfRange例外をスローします。これは、要素が選択されていない場合、インデックスが-1に等しいためです。

私はこのようにdown_clickを編集します:

private void down_click(object sender, RoutedEventArgs e)
{
    if (this.lbItems.SelectedIndex != -1) //Added condition
    {
        var selectedIndex = this.lbItems.SelectedIndex;
        if (selectedIndex + 1 < this.ListItems.Count)
        {
            var itemToMoveDown = this.ListItems[selectedIndex];
            this.ListItems.RemoveAt(selectedIndex);
            this.ListItems.Insert(selectedIndex + 1, itemToMoveDown);
            this.lbItems.SelectedIndex = selectedIndex + 1;
        }
    }
}
于 2013-09-27T06:58:58.920 に答える
1

これを試して:

if (listBoxDatasetValues.SelectedItems.Count > 0)
{
    object selected = listBoxDatasetValues.SelectedItem;
    int indx = listBoxDatasetValues.Items.IndexOf(selected);
    int totl = listBoxDatasetValues.Items.Count;

    if (indx == 0)
    {
        listBoxDatasetValues.Items.Remove(selected);
        listBoxDatasetValues.Items.Insert(totl - 1, selected);
        listBoxDatasetValues.SetSelected(totl - 1, true);
    }
    else{
        listBoxDatasetValues.Items.Remove(selected);
        listBoxDatasetValues.Items.Insert(indx - 1, selected);
        listBoxDatasetValues.SetSelected(indx - 1, true);
    }
}
于 2012-09-22T04:06:56.240 に答える
1
 if(listBoxDatasetValues.ListIndex > 0)
    {
        // add a duplicate item up in the listbox
        listBoxDatasetValues.AddItem(listBoxDatasetValues.Text, listBoxDatasetValues.ListIndex - 1);
        // make it the current item
        listBoxDatasetValues.ListIndex = (listBoxDatasetValues.ListIndex - 2);
        // delete the old occurrence of this item
        listBoxDatasetValues.RemoveItem(listBoxDatasetValues.ListIndex + 2);
    }
于 2012-09-22T04:25:01.863 に答える
0

あなたはこのようなことを試みるかもしれません:

上に移動する場合:

if (listboxName.SelectedIndex == -1 || listboxName.SelectedIndex == 0)
    return;

Object select, previous, temp;
select = listboxName.Items[listboxName.SelectedIndex];
previous = listboxName.Items[listboxName.SelectedIndex-1];

temp = select;
select = previous;
previous = temp;

listboxName.Items[listboxName.SelectedIndex] = select;
listboxName.Items[listboxName.SelectedIndex-1] = previous;

listboxName.SelectedIndex--;

下に移動する場合:

if (listboxName.SelectedIndex == -1 || listboxName.SelectedIndex == listboxName.Items.Count-1)
    return;     

Object select, next, temp;
select = listboxName.Items[listboxName.SelectedIndex];
next = listboxName.Items[listboxName.SelectedIndex+1];

temp = select;
select = next;
next = temp;

listboxName.Items[listboxName.SelectedIndex] = select;
listboxName.Items[listboxName.SelectedIndex+1] = next;

listboxName.SelectedIndex++;
于 2012-09-22T03:45:06.703 に答える
0

監視可能なコレクションを使用する必要はありません。ListBox内のコレクションオブジェクトに依存するだけで簡単に実行できます。@PeterHansenの回答の最適化されたバージョンは次のとおりです。

private void up_click(object sender, RoutedEventArgs e)
{
    var selectedIndex = this.lbItems.SelectedIndex;

    if (selectedIndex > 0)
    {
        var itemToMoveUp = this.lbItems.Items[selectedIndex];
        this.lbItems.Items.RemoveAt(selectedIndex);
        this.lbItems.Items.Insert(selectedIndex - 1, itemToMoveUp);
        this.lbItems.SelectedIndex = selectedIndex - 1;
    }
}

private void down_click(object sender, RoutedEventArgs e)
{
    var selectedIndex = this.lbItems.SelectedIndex;

    if (selectedIndex + 1 < this.lbItems.Items.Count)
    {
        var itemToMoveDown = this.lbItems.Items[selectedIndex];
        this.lbItems.Items.RemoveAt(selectedIndex);
        this.lbItems.Items.Insert(selectedIndex + 1, itemToMoveDown);
        this.lbItems.SelectedIndex = selectedIndex + 1;
    }
}
于 2020-10-16T16:55:17.067 に答える