2
votes

I'm trying to move a selected ListView item up / down via buttons. The item is deleted and inserted at the same index. But i want to add it at index+1 (down) or index -1 (up)

I've got 4 items and tried to move down item 2 (at index 1) Here's an example of my down_click procedure

private void down_Click(object sender, EventArgs e)
{
    ListViewItem selected = listView1.SelectedItems[0];
    int sel_index = listView1.SelectedItems[0].Index;
    int newindex = sel_index + 1;
    listView1.Items.RemoveAt(sel_index);
    listView1.Items.Insert(newindex, selected);
}
2
Make these changes in the source list and they should get reflected. - parveenkhtkr
what source list? I'm parsing a textfile at programm start and load it's contents to an array. Iterating through that array and adding the items to the ListView. - Knoffel
which platform are you building this on? WPF, Windows Form, Windows Universal? - parveenkhtkr
Windows Forms. C# .Net Framework 4.5 - Knoffel
And you do realize indexes change as soon as you have removed an item? - Mikko Viitala

2 Answers

1
votes

You should simply change the view mode of your listview to list :

listView1.View = View.List;

I hope it would help.

1
votes

Actually your code doesn't have any problem. The problem is with ListView.

When you use ListView with View property set to LargIcon (that is default value for view property), SmallIcon or Tile View, inserting items, doesn't work as expected but in List and Details View it works as expected.

To overcome this problem, you can do any of these:


Solution 1: (Workaround)


Set the View property of ListView to Details or List.


Solution 2: (Better and complete solution)


To overcome the problem in all Views, use this UpdateLayout method and call it after inserting item.

private void UpdateLayout()
{
    if (this.listView1.View == View.LargeIcon ||
        this.listView1.View == View.SmallIcon ||
        this.listView1.View == View.Tile)
    {
        listView1.BeginUpdate();
        //Force ListView to update its content and layout them as expected
        listView1.Alignment = ListViewAlignment.Default;
        listView1.Alignment = ListViewAlignment.Top;
        listView1.EndUpdate();
    }
}

So UpButton and DownButton code might be like this:

private void UpButton_Click(object sender, EventArgs e)
{
    //If there is a selected item in ListView
    if (this.listView1.SelectedIndices.Count >= 0)
    {
        //If selected item is not the first item in list 
        if (this.listView1.SelectedIndices[0] > 0)
        {
            var index = this.listView1.SelectedItems[0].Index;
            var item = this.listView1.SelectedItems[0];
            this.listView1.Items.RemoveAt(index);
            this.listView1.Items.Insert(index - 1, item);
            this.UpdateLayout();
        }
    }
}

private void DownButton_Click(object sender, EventArgs e)
{
    //If there is a selected item in ListView
    if (this.listView1.SelectedIndices.Count >= 0)
    {
        //If selected item is not the last item in list 
        if (this.listView1.SelectedIndices[0] < this.listView1.Items.Count - 1)
        {
            var index = this.listView1.SelectedItems[0].Index;
            var item = this.listView1.SelectedItems[0];
            this.listView1.Items.RemoveAt(index);
            this.listView1.Items.Insert(index + 1, item);
            this.UpdateLayout();
        }
    }
}

Additional Notes


To get a better look of ListView, Set these properties in designer or your code:

  • Set MultiSelect to false, to prevent select more than one item
  • Set FullRowSelect to true to enable selection by click everywhere in a row
  • Set HideSelection = false to highlight selected item even if ListView doesn't have focus