14

我正在尝试在自定义中实现搜索功能,ListView因此我隐藏Items了一个ObservableCollection允许的自定义AddRange,类似于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

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

问题是ListViewItems'Group并非始终如一地从this.Itemsto携带base.Items,因此所有项目都出现在“Default”组中。

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

更新

我仍然坚持这一点。当然这样做.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"

我还检查了这个替换MyCollection<为正常ObservableCollection<的,同样的情况仍然发生。

更新 3 - 解决方案

请看我的回答

4

1 回答 1

8

背景

弄清楚了!

我不知道为什么,但在应该抛出异常的时候却没有抛出异常。

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

(从 a 中清除一些东西后.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();
于 2012-10-12T15:44:09.940 回答