views:

918

answers:

3

Hi, I have another problem with ListView :( Now I need to move items in group (up, down, to the beginning, to the end), but ListView is displaying moved items always at the end.

Here is sample code for moving item to the beginning:

   if (1 == listView1.SelectedItems.Count)
    {

        ListViewItem item = listView1.SelectedItems[0];
        ListViewGroup gp = item.Group;

        int index;
        index = item.Index;

        if (index < listView1.Items.Count)
        {

            index = 0;

            listView1.Items.Remove(item);

            item.Group = gp;

            listView1.Items.Insert(index, item);
        }
    }

I tried google to find some solution, and I found someone else (http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/838f90cd-33d8-4c81-9ed9-85220b511afe) who had same problem like me, but his solution is not working :(

I considered using ObjectListView but I have modified ListView witch now supports drag & drop with WinAmp effect, onScroll events, scrolling synchronization etc.. and I don't want to lose this stuff :(

A: 

My automatic response to this question would be to check and see if it works if you say

listView1.Items.Count - 1

because the list is zero-indexed so the count is 1 greater than the last index)

I don't think this could be a problem.. For example: Listview with 4 items have first index 0, last index 3. if (index < listView1.Items.Count)- index 4 doesn't match this condition, because 4 == Count of items. With listView1.Items.Count - 1 if statement should look like this:if (index <= listView1.Items.Count - 1)
Klinki
A: 

Looking at the code, it has a few problems which make me curious. It looks like what may be the problem is the intial if statement. If there is only 1 item in the itemlist, then removing it and re-adding it will not do anything regardless of where you stick it. I believe you want <=

Also, you're setting the index to 0 right after getting it from the item you're interested in. If the code is supposed to move it to the top, Index=0 should be moved inside the if statement.

Not sure if those will solve the problem though...

Kurisu
First if means if there is only 1 SELECTED item, not 1 item in ListView :-) And with index = 0 you were right... I corrected it, but it didn't solved the problem.
Klinki
Oh! Selected items. I misread. I would guess that the problem then is with listView1.Items.Insert(index, item); I would slap a debug statement there and check all your variables to make sure they're good, and then see if you can step inside that to see if it's going to some user defined code elsewhere.
Kurisu
+2  A: 

Try this:

/// <summary>
/// Move the given item to the given index in the given group
/// </summary>
/// <remarks>The item and group must belong to the same ListView</remarks>
public void MoveToGroup(ListViewItem lvi, ListViewGroup group, int indexInGroup) {
    group.ListView.BeginUpdate();
    ListViewItem[] items = new ListViewItem[group.Items.Count + 1];
    group.Items.CopyTo(items, 0);
    Array.Copy(items, indexInGroup, items, indexInGroup + 1, group.Items.Count - indexInGroup);
    items[indexInGroup] = lvi;
    for (int i = 0; i < items.Length; i++)
        items[i].Group = null;
    for (int i = 0; i < items.Length; i++) 
        group.Items.Add(items[i]);
    group.ListView.EndUpdate();
}
Grammarian
This throws System.ArgumentException "Cannot add or insert the item '' in more than one place.
Klinki
This is production code -- I *know* it works. So, could you tell me a little more about what is happening when it throws the exception? Which line? What is the value of indexInGroup? How many items does the group already have? [I'm also assuming you paid attention to the remarks section]
Grammarian
Oh I'm idiot :D I assigned 1 group to 3 ListViews... It was in different block of code so I noticed it when you said that your code works... Now it really works. Thanks!
Klinki
+9000. Don't know just how much time I've wasted on this. Thank you.
Yoopergeek