.NET: блюз ListView?

Счетчик выбора, .SelectedItems.Count, не изменяется, когда для свойства Selected установлено значение true для элемента в коллекции Items коллекции ListView.

Пример:

  lvPept.SelectedItems.Clear()
  lvPept.Items(6).Selected = True
  Dim newLen As Integer = lvPept.SelectedItems.Count

lvPept это ListView и содержит 10 элементов.

Ожидается, что newLen будет равно 1, но будет равно 0, если возникнет проблема, а событие SelectedIndexChanged не будет запущено. Для других наборов данных он равен 1, как и ожидалось, и запускается событие SelectedIndexChanged.

При каких обстоятельствах или в каком состоянии может находиться lvPept, чтобы это произошло? BeginUpdate()/EndUpdate() не используется с lvPept.

Фон:

Я пытаюсь отследить проблему одного из пользователей моего приложения .NET с открытым исходным кодом, MSQuant (http://msquant.sourceforge.net/).

У меня закончились идеи о том, что может быть причиной этой проблемы.

Проблема воспроизводима, и я могу воспроизвести ее в своей среде разработки Visual Studio 2008. Кажется, она не зависит от версии Windows (Windows 2000/Windows XP 32-разрядная/Windows XP 64-разрядная), версии среды выполнения .NET (2.0 /3.5) и версии Visual Studio (2005/2008).

Другой контекст: приложение написано на VB.NET и C# и является приложением Windows Forms. Исходный код рассматриваемого класса находится по адресу http://shrinkster.com/14bg. Класс формы, в котором находится ListView, изначально был сгенерирован одной из самых ранних официальных версий Visual Studio, которая поддерживала .NET, ок. 2002.

Обновление 1: поскольку у меня есть как рабочий, так и сломанный чехол, я сравнил содержимое lvPept. Единственным отличием, кроме свойств "Handle", "MousePosition" и "TopItem" (поскольку это другой белок с другими пептидами), является свойство "Created". Это было False для сломанного корпуса. Понятно, что частично построенный объект не может функционировать должным образом, но как это может произойти?

Обновление 2: свойство «Создано», являющееся ложным, оказалось хорошей зацепкой. Я думаю, что настоящая проблема заключалась в том, чтобы сделать это во время строительства, а не во время загрузки формы. Теперь я добавил ASSERT для свойства «Создано», провел рефакторинг и изменил все операции, которые должны выполняться во время загрузки формы. Теперь оно работает должным образом, и пользователь с проблемой получил новую версию приложения.

Старый плохой способ был там с момента создания приложения в 2002 году. Мне просто интересно, могут ли некоторые эксперты пролить свет на то, почему он работал в 99,9% случаев и терпел неудачу только в нескольких случаях и воспроизводимо.


person Peter Mortensen    schedule 11.02.2009    source источник


Ответы (2)


Это интересно.

Единственное, что, по моему мнению, могло бы произойти, это если бы ListView не понял, что ListItem изменил свое значение «Выбрано» и, следовательно, не обновляет свои коллекции выбранных элементов.

Свойство .SelectedItems не обязательно создается каждый раз, когда вы получаете свойство, если вы отражаете сборку System.Windows.Forms:

    if (this.selectedListViewItemCollection == null)
    {
        this.selectedListViewItemCollection = new SelectedListViewItemCollection(this);
    }
    return this.selectedListViewItemCollection;

Поэтому я склонен думать, что вы получаете устаревшую коллекцию selectedListViewItemCollection.

Я бы попробовал вместо изменения свойства Selected на уровне элемента попробовать вместо этого добавить выбранный индекс в свойство .SelectedIndices ListView и посмотреть, работает ли это. Таким образом, ListView не полагается на изменение ListViewItem.

person Brandon    schedule 11.02.2009

Я считаю, что вам также нужно вызвать ListView.Select(), чтобы запустить событие SelectedIndexChanged.

lvPept.SelectedItems.Clear()
lvPept.Items(6).Selected = True
lvPept.Select()
Dim newLen As Integer = lvPept.SelectedItems.Count
person scottm    schedule 11.02.2009