Группа ListViewItem не сохраняется через другую коллекцию - программирование
Подтвердить что ты не робот

Группа ListViewItem не сохраняется через другую коллекцию

Я пытаюсь реализовать функцию поиска в пользовательском 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.

Это работает отлично и, как ожидалось, за исключением небольшого, но важного оговорки:

Проблема заключается в том, что ListViewItem s 'Group не всегда переносится от this.Items до base.Items, и поэтому все элементы отображаются в группе "По умолчанию".

Любые идеи относительно того, почему это происходит и как это исправить?

Update

Я все еще придерживаюсь этого. Разумеется, .ToArray() создает мелкую копию Items, поэтому сохранить Group? Это подтверждено Maverik:

Я только что позвонил в Linqpad, и хотя ссылка на список отличается, вы правы.. ссылки на объекты одинаковы.

Обновление 2

Хорошо, после нескольких исследований я обнаружил, где это происходит.

При добавлении 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<, и то же самое происходит.

Обновление 3 - Решение

Пожалуйста, см. мой ответ.

4b9b3361

Ответ 1

Фон

Выяснилось!

Я не знаю, почему, но исключение не было брошено, когда это должно было быть.

Необходимо исключить исключение 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});

Это были лишь некоторые временные элементы, которые я добавил ранее для теста, но разработчик, должно быть, помнил их по какой-то причине.)


Решение

Решение такое, как описано в этом ответе SO, и мой код теперь читает:

this.BeginUpdate();
base.Items.Clear();
base.Items.AddRange(this.Items.Select((ListViewItem)a => a.Clone()).ToArray());
this.EndUpdate();