Reputation: 31623
Selection count, .SelectedItems.Count
, does not change when
the Selected
property is set to true on an item in the Items
collection of a ListView
.
Example:
lvPept.SelectedItems.Clear()
lvPept.Items(6).Selected = True
Dim newLen As Integer = lvPept.SelectedItems.Count
lvPept
is a ListView
and contains 10 elements.
newLen
is expected to be 1, but is 0 when the problem occurs
and the SelectedIndexChanged
event is not fired. With
other datasets it is 1 as expected and the
SelectedIndexChanged event is fired.
Under what circumstance or in what state can lvPept
be in
for this to happen? BeginUpdate
()/EndUpdate
() is not
used with lvPept
.
Background:
I am trying to track down a problem one of the users of my open source .NET application, MSQuant (http://msquant.sourceforge.net/), encountered.
I have run out of ideas of what could be the cause of this problem.
The problem is reproducible, and I can reproduce it in my development environment, Visual Studio 2008. It seems to be independent of the Windows version (Windows 2000/Windows XP 32 bit/ Windows XP 64 bit), the .NET runtime version (2.0/3.5) and Visual Studio version (2005/2008).
Other context: the application is written in VB.NET and in
C# and is a Windows Forms application. The source code for the
class in question is at http://shrinkster.com/14bg. The
form class that the ListView
is in was initially generated
by one of earliest official versions of Visual Studio that
supported .NET, ca. 2002.
Update 1: as I have both a working case and a broken case I
have compared the content of lvPept
. The only difference
except for properties "Handle", "MousePosition" and "TopItem"
(as it is a different protein with different peptides) is property
"Created". It was False for the broken case. It makes sense
that a partly constructed object can not function properly,
but how can it happen?
Update 2: property "Created" being false turned out to be a good lead. I think the real problem was doing this at construction time and not at form load time. I have now added ASSERTs for property "Created", refactored and changed all the operations to happen at form load time. It now works as expected and the user with the problem has got a new version of the application.
The old bad way had been in there since the application's inception in 2002. I am just wondering if some experts could throw light on why it worked 99.9% of the time and only failed in a few cases and reproducably so.
Upvotes: 4
Views: 1287
Reputation: 28699
I believe you also have to call ListView.Select() in order to fire the SelectedIndexChanged event.
lvPept.SelectedItems.Clear()
lvPept.Items(6).Selected = True
lvPept.Select()
Dim newLen As Integer = lvPept.SelectedItems.Count
Upvotes: 0
Reputation: 14196
That's an interesting one.
The only thing that I think could make this happen is if the ListView didn't realize that the ListItem had changed it's "Selected" value and therefore doesn't update its selected item collections.
The .SelectedItems property is not necessarily generated each time you get the property - if you reflect the System.Windows.Forms assembly:
if (this.selectedListViewItemCollection == null)
{
this.selectedListViewItemCollection = new SelectedListViewItemCollection(this);
}
return this.selectedListViewItemCollection;
So I'm inclined to think that you're getting an out-of-date selectedListViewItemCollection.
I would try instead of changing the Selected property at the Item level, try instead adding the selected index to the .SelectedIndices property of the ListView and see if that works. That way the ListView isn't relying on picking up a ListViewItem change.
Upvotes: 1