Skip to content

ListViewGroupCollection.Add can cause corruption adding a group already added to another ListView #4001

@hughbe

Description

@hughbe
  • .NET Core Version:
    Master

  • Have you experienced this same bug with .NET Framework?:
    Yes

Problem description:

  • Add a ListViewGroup to listView1.Groups
  • Add the same ListViewGroup to listView2.Groups

See below test: it is very odd that group.ListView == otherListView but both otherListView.Groups and listView.Groups contain group

[WinFormsFact]
public void ListViewGroupCollection_Addd_AlreadyInOtherCollection_GetReturnsExpected()
{
    using var listView = new ListView();
    ListViewGroupCollection collection = listView.Groups;

    using var otherListView = new ListView();
    ListViewGroupCollection otherCollection = otherListView.Groups;

    var group = new ListViewGroup();
    otherCollection.Add(group);

    // The group appears to belong to two list views.
    collection.Add(group);
    Assert.Same(group, collection[0]);
    Assert.Same(listView, group.ListView);
    Assert.Equal(group, Assert.Single(collection));
    Assert.Equal(group, Assert.Single(otherCollection));
}

Expected behavior:
Which one? I don't really know!

  • We throw an ArgumentException or InvalidOperationException when adding/inserting/setting?
  • Do nothing if group.ListView != null (nop) and return -1
  • Remove group from the other ListViewGroupCollection?

I presume the bug also exists for Item.Set and Insert

Note: implementation of ListViewGroupCollection.Add:

public int Add(ListViewGroup group)
{
    if (group is null)
    {
        throw new ArgumentNullException(nameof(group));
    }

    if (Contains(group))
    {
        return -1;
    }

    CheckListViewItems(group);
    group.ListView = _listView;
    int index = List.Add(group);
    if (_listView.IsHandleCreated)
    {
        _listView.InsertGroupInListView(List.Count, group);
        MoveGroupItems(group);
    }

    return index;
}

Minimal repro:
See above

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions