我正在尝试在自定义ListView
中实现搜索功能,因此我隐藏Items
一个自定义ObservableCollection
,允许AddRange
,类似于one defined on damonpayne.com(对于tl; dr-ers在那里基本上它会抑制触发OnCollectionChanged
事件,同时添加多个项目然后使用NotifyCollectionChangedAction.Reset
触发):
public new MyCollection<ListViewItem> Items { get; protected set; }
MyCollection_CollectionChanged()
填充base.Items
:
this.BeginUpdate();
base.Items.Clear();
base.Items.AddRange(this.Items.ToArray());
this.EndUpdate();
这个想法是,当项目不符合搜索条件时,它们将从base.Items
(即 System.Windows.Forms.ListView )中删除,但仍保留在this.Items
中(即 My.Name.Space.MyListView )。取消搜索或更改字词后,base.Items
可以重新填充this.Items
。
除了一个小但重要的警告之外,这种方法很好并且符合预期:
问题在于ListViewItem
s Group
并非始终从this.Items
传递到base.Items
,因此所有项目都显示在“默认”组中。
关于为什么会发生这种情况以及如何解决问题的想法?
我仍然坚持这一点。当然.ToArray()
只是创建Items
的浅表副本,以便保留Group
?
这已由Maverik确认:
好的,经过一些调查,我发现了它的发生地点。
将ListViewItem
添加到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"
我还检查了这个用正常MyCollection<
替换ObservableCollection<
,但仍然会发生同样的情况。
答案 0 :(得分: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});
这些只是我之前为测试添加的一些临时项目,但设计师必须因某些原因记住它们。)
解决方案如this SO answer中所述,我的代码现在为:
this.BeginUpdate();
base.Items.Clear();
base.Items.AddRange(this.Items.Select((ListViewItem)a => a.Clone()).ToArray());
this.EndUpdate();