使用数据源在列表框中移动所有选定的项目

时间:2018-11-20 07:12:50

标签: c# .net winforms

我有一个ListBox,其中一个ObservableCollection<string>作为其DataSource。现在,我希望能够上下移动每个选定的项目。因此,如果列表看起来像这样(所选项目的前缀为*

  Item 1
* Item 2
  Item 3
* Item 4
* Item 5
* Item 6
  Item 7

我希望它在向下移动一次后看起来像这样:

  Item 1
  Item 3
* Item 2
  Item 7
* Item 4
* Item 5
* Item 6

或上移一次后的情况:

* Item 2
  Item 1
* Item 4
* Item 5
* Item 6
  Item 3
  Item 7

我已经偶然发现ObservableCollection<T>.Move(int oldIndex, int newIndex),但是我只能让它与移动单个项目一起使用。

什么是好的算法?

2 个答案:

答案 0 :(得分:0)

如果所有选定的行都没有间隙地掉落,将更容易(在某些情况下,对用户而言更直观),但是应该可以实现任何一种方式。您可以绝对使用ObservableCollection的Move()方法,要移动多个,您必须将多个startindex(针对每个选定项)收集到一个列表中,然后使用Move()方法在该列表中进行迭代以及进行一些基于光标在哪个索引位置上以及所选项目的排序顺序,以确定每个项目的“ newindex”是什么。

编辑:还请记住更改计算中必须适应的索引的多米诺骨牌效应。

答案 1 :(得分:0)

正如我在评论中已经提到的那样。您可以使用前进和后退循环来完成此操作。这是完成此任务的示例程序。我使用按钮来区分向上和向下运动:

ObservableCollection<string> source = new ObservableCollection<string>();
private void Form1_Load(object sender, EventArgs e)
{
    for (int i = 1; i < 10; i++)
    {
        source.Add("Item " + i);
    }

    listBox1.DataSource = source;
}

private void buttonMoveUp_Click(object sender, EventArgs e)
{
    foreach (int index in listBox1.SelectedIndices)
    {
        if (index > 0) // don't move the first element upwards
        {
            source.Move(index, index - 1);
        }
    }

    listBox1.DataSource = null;
    listBox1.DataSource = source;
}

private void buttonMoveDown_Click(object sender, EventArgs e)
{
    for (int i = listBox1.SelectedIndices.Count - 1; i >= 0; i--)
    {
        int index = listBox1.SelectedIndices[i];
        if (index < source.Count-1) // don't move the last element downwards
        {
            source.Move(index, index + 1);
        }
    }            

    listBox1.DataSource = null;
    listBox1.DataSource = source;
}