//
you're reading...
.NET 2.0

Getting along with ListView’s VirtualList mode (Part 3)

Disclaimer: Since this post will live long after the next releases of Visual Studio it is important that what I mention here only applies to the November 2004 CTP of Visual Studio 2005. What I’m mentioning here may no longer apply with current releases. I do have the December 2004 CTP of Visual Studio 2005 with Team System yadda yadda, but I was unable to get it working on my system.

Kind of backwards, but I didn’t feel like opening Visual Studio so I thought I’d make another post in this spontaneous series this time focusing on using the VirtualListMode to display and search for items in your list.

Using the virtual mode requires doing three things and not doing one thing. First, set the VirtualMode property to true; second, handle the RetrieveVirtualItem event setting the Item property of the event args to an instance of a ListViewItem representing the index requested; third, set the VirtualListSize property to the number of items the ListView should contain. And never, under any circumstance attempt to access any property that deals with ListViewItems directly; that means the Items and SelectedItems properties are off-limits (now you know why I used the SelectedIndices property in my first post).

Example and much more will continue when you read the extended entry.

For example:

myListView.VirtualMode = true;
myListView.RetreiveVirtualItem += new RetrieveVirtualItemEventHandler( this.RetrieveVirtualItem );
myListView.VirtualListSize = 100000;

private void RetreiveVirtualItem( object sender, RetrieveVirtualItemEventArgs e )
{
  e.Item = new ListViewItem( e.ItemIndex.ToString() );
}

This will create a ListView in virtual mode that will have 100,000 items in it. It appears that the number of items specified by the VirtualListSize property dictates some linear process in the ListView itself so it isn’t possible to replicate the “billion” row grid that some other vendors use as an example.

Now the next part and why I’m writing this is how you deal with other events exposed by the ListView: CacheVirtualItems, SearchForVirtualItem, and VirtualItemsSelectionRangeChanged.

One by one, here we go:

CacheVirtualItems

This event gets fired whenever the ListView is about to ask for one or more ListViewItems via the RetreiveVirtualItem event. This is only a friendly warning so you can preload some data if needed.

SearchForVirtualItem

This event is fired in tandem with the ListView‘s FindItem and FindNearestItem methods. Unfortunately there are a few problems with it as is. If you don’t keep your ListViewItem’s around after you dispense of them via the RetreiveVirtualItem event, then the ListViewItem returned by the FindItem/FindNearestItem methods are pretty much useless.

Basically you need to use the data provided by the event to fill in the event args Item property with the ListViewItem that matches the data passed in.

What would make this event more useful is if instead of returning a ListViewItem if an index was returned which would then be used by the RetreiveVirtualItem event. That way you only have one place creating ListViewItems and if the ListViewItem found hadn’t been requested yet, modifying its properties and calling its methods would do something.

For example: Our ListView has a couple hundred items in it but only the first 50 have been requested. The user then starts typing into a textbox at which point you want the ListView to scroll down to the item closest matching what was typed. You would think that you could just use the FindItem method to get the closest matching ListViewItem and call EnsureVisible() on it. And that might work if you don’t use VirtualMode. But since we are using VirtualMode, the ListViewItem returned by FindItem() isn’t associated in anyway with the ListView so doing anything with it results in nothing happening. If, however, the search event fired when in VirtualMode was based on an item index then there would be an opportunity for standard code to work — new items are always created in some relation to the RetreiveVirtualItem event — and the ListViewItem would be associated with the ListView so modifying its properties and calling its methods would do something.

Notice, I was very specific in my example. If you change this slightly and instead cache ListViewItem’s as they are created and the item found was one of those cached items then changing the properties and calling it’s methods does have an affect.

VirtualItemsSelectionRangeChanged

Another broken event. This event is supposed to tell you when a range of items in the ListView has had its selection change, but it only handles using the keyboard and keyboard/mouse to select items and even then it gets the range wrong. If you only use the mouse to select a range of items, the event simply tells you that every item in the view was not selected. If you use the keyboard to select a range of items by holding shift as you arrow through them, then starting with at least two items selected it will give the correct start index, but the end index will be one less than it should be. IOW, if you just selected items 2, 3, 4, and 5; it would say the start index was 2 and end index was 4. The behavior is the same if you select one item, hold down shift, and click on another item. The event also does not handle non-contiguous ranges being selected.

I think a better solution would look something like this:

First the selection is cleared, then items 5-10 are selected, then Ctrl is held and item 13 is added to the selection, again while Ctrl is held item 6 is removed from the selection.

The VirtualItemsSelectionRangeChanged event would be fired with these arguments…I’m torn over the first set though, either using -1 for the Start/End Indexs could be used to earmark the selection being completely cleared or stick with the current StartIndex=0 EndIndex=n-1 (where n is the number of items in the ListView).

StartIndex EndIndex IsSelected
-1 -1 false
5 10 true
13 13 true
6 6 false

What happened? I didn’t intend for this to turn into an article!

It is obvious at this point that the VirtualMode is still a work in progress in this CTP of the Framework, but hopefully someone at Microsoft will see these suggestions and adapt them in some way with the ListView control.

If anyone knows that this information is incorrect either in the build I’m using or a later one leave me a comment so I can update this post.

Advertisements

About James

I am a Senior Developer/Consultant for InfoPlanIT, LLC. I previously spent over 7 years as a Product Manager for what eventually became ComponentOne, a division of GrapeCity. While there, I helped to create ActiveReports 7, GrapeCity ActiveAnalysis, and Data Dynamics Reports.

Discussion

9 thoughts on “Getting along with ListView’s VirtualList mode (Part 3)

  1. nice and useful article….
    I get the following error…….
    “When the ListView is in virtual mode, you cannot add items to the ListView items collection. Use the VirtualListSize property instead to change the size of the ListView items collection.” in whidbey beta
    could u provide working example code that will be useful for beginners like me…..

    Posted by rajesh | December 19, 2005, 12:04 am
  2. Pretty good.
    How can I add items in a virtual list?
    Pls provide more info related to virtuallist
    thanks

    Posted by muthu | January 3, 2006, 12:25 am
  3. Microsoft has posted a nice example here:
    http://www.windowsforms.com/ControlGallery/ControlDetail.aspx?Control=214&tabindex=9

    The VirtualItemsSelectionRangeChanged event does appear to have funny behaviour

    Posted by Jud | February 10, 2006, 4:28 pm
  4. How do I add an image to the ListViewItem?

    I mean when I create a new instance of the object and assign a picture string key to it the ImageList of the ListViewItem=null.

    Posted by Hawk | February 14, 2006, 11:22 am
  5. Have you ever tried to use CheckBoxes with a VirtualMode ListView ?
    I cannot seem to get it to work.

    At least partially ….

    If I loop throungh all the items in my List and set their Checked proerty to true. When RetrieveVirtualItem is called I ser the ListViewItem Checked property to the equivalent List item property.
    The check boxes then appear and are checked.

    If I then go and set them all to false the check boxes “disappear” completely

    Please can you help me.

    Posted by Robert | May 25, 2006, 5:32 am
  6. Have you ever tried Groups in virtual mode?
    i get it to work without virtual mode. but not with it.

    Posted by Flow84 | July 19, 2006, 6:43 pm
  7. @Flow84: read here http://blogs.msdn.com/cumgranosalis/archive/2006/03/06/VirtualListViewUsage.aspx

    it says that groups do not work with virtual mode enabled.

    Posted by dahead | October 3, 2006, 9:15 am
  8. Holy crap, dahead I’m surprised you made it through the article. I didn’t realize the new theme I’m using did this to code tags.

    Thanks for all the comments everyone.

    Posted by james | October 3, 2006, 6:07 pm
  9. seems the first selecting in the listview(virtualmode) would not trigger the event “VirtualItemsSelectionRangeChanged”.

    Posted by mellon | August 15, 2011, 4:15 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archive

%d bloggers like this: