WPF: SelectedItems с повторяющимися ссылками на объекты

Итак, скажем, у меня есть эти классы:

public class Person
{
     public string Name { get; set; }
}
public class PersonCollection : ObservableCollection<Person> { }

Допустим, у меня есть ListView, ItemsSource которого привязан к PersonCollection. Теперь скажем, у меня есть этот код:

public void AddPeople()
{
     Person p = new Person() { Name = "Someone" };
     MyPersonCollection.Add(p);
     MyPersonCollection.Add(p);
     MyPersonCollection.Add(p);
}

Итак, теперь у меня есть ListView с тремя элементами, в которых все три элемента являются ссылками на ОДИН и тот же объект. Итак, теперь я выбираю, скажем, элементы с индексом 0 и 2 в ListView.

Свойство ListView.SelectedItems сообщит, что у меня выбран ОДИН элемент, поскольку оба визуально выбранных элемента являются ОДНИМ и ОДНИМ объектом.

Итак, как я могу получить визуально выбранные элементы, чтобы удалить элементы с индексами 0 и 2, не удаляя элемент с индексом 1?


person Nick    schedule 11.03.2009    source источник


Ответы (3)


В WinForms есть свойство ListBox.SelectedIndices, которое было бы здесь полезно, но, к сожалению, в WPF его нет...

Вы можете выполнить итерацию по ListViewItem, используя ItemContainerGenerator.ContainerFromIndex установите флажок ListViewItem.IsSelected и затем удалите их по индексу. Однако это не очень хорошо сочетается с виртуализацией, потому что ContainerFromIndex может возвращать значение null, если вы прокручиваете элемент, и он становится виртуализированным.

Код будет выглядеть примерно так:

for(int ixPerson = myListView.Items.Count - 1; ixPerson >= 0; ixPerson--)
{
   ListViewItem personItem = myListView.ItemContainerGenerator.ContainerFromIndex(ixPerson);
   if (personItem.IsSelected)
   {
      mySourcePersonCollection.RemoveAt(ixPerson);
   }
}
person Robert Macnee    schedule 11.03.2009
comment
Спасибо, это сработало. Я не совсем уверен, что вы имеете в виду под виртуализацией, но с тем простым проектом, который мы делаем, нам этого будет вполне достаточно. Спасибо. - person Nick; 11.03.2009
comment
Я имею в виду, что иногда не каждый человек в коллекции Items будет иметь ListViewItem из-за виртуализации. Если вы выберете первого человека в ListView, а затем прокрутите вниз, чтобы он исчез, возможно, вызов ItemContainerGenerator.ContainerFromIndex(0) вернет значение null. - person Robert Macnee; 12.03.2009

Есть случаи, когда это имеет смысл, например, добавление людей в очередь, где желательно появляться более одного раза. В этом случае кажется, что WPF разработан плохо. Можно ли вручную перебирать все элементы в коллекции и проверять их состояние выбора?

person Michael    schedule 11.03.2009
comment
Я пока ничего подобного не нашел, но было бы неплохо. - person Nick; 11.03.2009

Я думаю, что-то не так с вашей моделью! Чего бы вы ни пытались достичь, я бы попытался найти более надежный способ сделать это.

person amaca    schedule 11.03.2009
comment
Что ты имеешь в виду? Может быть, это та функциональность, которую я хочу. Если у вас проблемы с моей бизнес-логикой, оставьте меня в покое. - person Nick; 11.03.2009