dotnet / dotnet/winforms

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

Open
#4,001 6 comments 0 reactions 0 assignees View on GitHub
:beetle: bug :construction: work in progress area-controls-ListView
Dominant language
C#
Stars
4.9k
Forks
1.1k
Avg merge
20h 23m
Merged PRs (30d)
103

Description

* .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`

```cs
[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`:
```cs
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

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.