Hello,

I'm trying to move listView items (1 selected item only) up & do, but only inside the group, I've trying and search but haven't been able to quiet figure it out, this is what I got so far:

Just for going up:

if (this.listView1.SelectedItems.Count > 0)
{
    ListViewItem Selected = this.listView1.SelectedItems[0];
    ListViewGroup SelectedGroup = new ListViewGroup(this.listView1.SelectedItems[0].Group.Header);

    int phIndex = Selected.Index;;

    if (Selected.Group.Header == this.listView1.Items[phIndex - 1].Group.Header)
    {
        if (phIndex != 0)
        {
            this.listView1.Items.RemoveAt(Selected.Index);
            this.listView1.Items.Insert(phIndex - 1, Selected);
            this.listView1.Groups.Insert(phIndex, SelectedGroup);
        }
    }
}

Item needs to move up inside the group.

So what is it doing? Did you call Refresh() on the ListView so it would redraw? Why are you looking at the one previous to the first selected in line 8?

Maybe you can explain better what you want to have happen by showing an example.

Edited 3 Years Ago by Momerath

What its doing is it removes and adds the item like it should but its not putting it in the group, its going to "Default"

I've been messing with "this.listView1.Groups.Insert(phIndex, SelectedGroup);" a lot but idk if thats the part thats wrong

Edited 3 Years Ago by iFrolox: .

Umh, nothing seems to be working.. This is what I got to far (just "Up)

private void phUp_MouseClick(object sender, MouseEventArgs e)
        {
            try
            {
                if (this.listView1.SelectedItems.Count > 0) //check if an item is selected
                {
                    if (this.listView1.SelectedItems[0].Index != 0) //make sure that the item is not the first item on the listView
                    {
                        foreach (ListViewGroup LVG in this.listView1.Groups) //go through each group
                        {
                            if (this.listView1.SelectedItems[0].Group.Header == this.listView1.Items[this.listView1.SelectedItems[0].Index - 1].Group.Header) //if item's group is the same as group as the item above it
                            {
                                ListViewItem LVI = this.listView1.SelectedItems[0];
                                LVI.SubItems[1].Text = this.listView1.SelectedItems[0].SubItems[1].Text;

                                int phIndex = LVI.Index;

                                this.listView1.Items.RemoveAt(phIndex);
                                this.listView1.Items.Insert((phIndex - 1), LVI);
                                LVG.Items.Insert((phIndex - 1), LVI);                         
                                break;
                            }
                        }                    
                    }
                }
            }
            catch { }
        }

Swapping listviewitems is problematic at best. I think the problems stems from the fact that Insert creates a new item. The most viable solution is probably to swap the data of the items. Here's one way that can be done, this code is somewhat optimized and modified for groups, from the one here:

    private void btnUp_Click(object sender, EventArgs e)
    {
        MoveListViewItem(ref listView1, Directions.UP);

    }
    private void btnDown_Click(object sender, EventArgs e)
    {
        MoveListViewItem(ref listView1, Directions.DOWN);
    }

    public enum Directions { UP = -1, DOWN = 1 }

    private void MoveListViewItem(ref ListView lv, Directions move)
    {
        ListViewItem currentitem =  lv.SelectedItems[0];
        ListViewGroup currentgroup =currentitem.Group;
        int selIdx = currentgroup.Items.IndexOf(currentitem);
        if (selIdx == 0 && move == Directions.UP)
        {
            //Replace these lines with return;, to eliminate wrap around
            currentgroup.Items.RemoveAt(0);
            currentgroup.Items.Add(currentitem);
        }
        else
            if (selIdx == currentgroup.Items.Count - 1 && move == Directions.DOWN)
            {
                //Replace these lines with return;, to eliminate wrap around
                for (int i = selIdx; i >= 1; i--)
                {
                    SwapLvItems(i, i - 1, currentgroup.Items);
                }
            }
            else
                SwapLvItems(selIdx, selIdx + (int)move, currentgroup.Items);
            lv.Refresh();
            lv.Focus();
    }
    private void SwapLvItems(int selIdx1, int selIdx2, ListView.ListViewItemCollection currentitems)
    {
        string cache;            
        for (int i = 0; i < currentitems[selIdx1].SubItems.Count; i++)
        {
            cache = currentitems[selIdx2].SubItems[i].Text;
            currentitems[selIdx2].SubItems[i].Text =
              currentitems[selIdx1].SubItems[i].Text;
            currentitems[selIdx1].SubItems[i].Text = cache;
        }
        currentitems[selIdx2].Selected = true; 
    }

This code uses wrap around. To have the scrolling stop at the ends, follow the comments in the code.

Edited 3 Years Ago by tinstaafl

Comments
Solved my problem :)
This question has already been answered. Start a new discussion instead.