ListViewItem的组未通过其他集合保留

dav*_*v_i 14 c# listview .net-3.5 winforms

我正在尝试在自定义中实现搜索功能,ListView因此我隐藏Items了一个ObservableCollection允许的自定义AddRange,类似于在damonpayne.com上定义的那个(对于tl; dr-ers在那里基本上它会抑制触发OnCollectionChanged事件,同时添加多个项目随后发射NotifyCollectionChangedAction.Reset):

public new MyCollection<ListViewItem> Items { get; protected set; }
Run Code Online (Sandbox Code Playgroud)

MyCollection_CollectionChanged()填充base.Items:

this.BeginUpdate();
base.Items.Clear();
base.Items.AddRange(this.Items.ToArray());
this.EndUpdate();
Run Code Online (Sandbox Code Playgroud)

这个想法是,当项目不满足搜索条件时,它们将从base.Items(即System.Windows.Forms.ListView)中删除,但保留在this.Items(即My.Name.Space.MyListView)中.取消搜索或更改条款时,base.Items可以重新填充this.Items.

除了一个小但重要的警告之外,这个工作正常并且符合预期:

问题是,ListViewItemS' Group是不是一直被从携带this.Itemsbase.Items,因此所有的项目出现在组'默认’.

关于为什么会发生这种情况以及如何解决问题的任何想法?

更新

我仍然坚持这个.肯定做的.ToArray()只是创建一个浅的副本,Items所以Group应该保留?Maverik已经证实了这一点:

我只是在Linqpad中调用,虽然列表引用不同,但你是对的..对象引用是相同的.

更新2

好的,经过一些调查我发现它发生了什么.

ListViewItems 添加到MyCollection<ListViewItem>:

var item0 = new ListViewItem();
var item0.Group = this.Groups["foo"];
//here this.Items.Count = 0
this.Items.Add(item0); 
//here this.Items.Count = 1 with item0 having group "foo"

var item1 = new ListViewItem();
var item1.Group = this.Groups["bar"];
//here this.Items.Count = 1 with item0 having group "foo"
this.Items.Add(item1);
//here this.Items.Count = 2 with item0 having group "null" and item1 having group "bar"
Run Code Online (Sandbox Code Playgroud)

我也检查了这个替换MyCollection<正常ObservableCollection<,同样仍然发生.

更新3 - 解决方案

参阅我的回答.

dav*_*v_i 8

背景

弄清楚了!

我不知道为什么,但应该有一个异常没有抛出.

异常Cannot add or insert the item 'item0' in more than one place.应该被抛出.

(从清除了一些东西之后.designer.cs,它被抛出(虽然好奇地没有穿过......)

根据要求,从包含自定义的表单的设计者清除的代码ListView

this.ListView.Items.AddRange(new System.Windows.Forms.ListViewItem[] {
    listViewItem1,
    listViewItem2,
    listViewItem3,
    listViewItem4,
    listViewItem5,
    listViewItem6});
Run Code Online (Sandbox Code Playgroud)

这些只是我之前为测试添加的一些临时项目,但设计师必须因某些原因记住它们.)


解决方案

解决方案如本SO答案中所述,我的代码现在为:

this.BeginUpdate();
base.Items.Clear();
base.Items.AddRange(this.Items.Select((ListViewItem)a => a.Clone()).ToArray());
this.EndUpdate();
Run Code Online (Sandbox Code Playgroud)