Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all articles
Browse latest Browse all 1448

[VB6] Virtual 5.0 ListView

$
0
0
Here is another take on the classic vbVision Virtual ListView from 2001.

It has been substantially reworked to remove the IDE-testing dependency on the old Dbgwproc.dll that most people don't even have installed anymore. This rendition also enables item icons and indenting, minor enough features but easy enough to implement. You could expand this to add column header sort indicators or other features.

This is a UserControl wrapper for the 5.0 ListView that shipped with VB5 and VB6. Comments are left to help you try to modify it for the 6.0 ListView, but as written it works with the 5.0 ListView (COMCTL32.OCX). Since the 5.0 ListView can be upgraded to a Common Controls 6.0 ListView using a simple SxS manifest most people do not use the "Visual Basic 6" MSCOMCTL.OCX anymore anyway though.


Virtual ListView?

The idea here is that unlike in default mode where the ListView stores the item and subitem collections, a virtual ListView relies on your program to maintain the underlying datastore. This buys you a couple of things:

  • No data duplication. The ListView only needs copies of the elements currently being displayed. This can save on RAM, especially for large data sets.
  • Fast scrolling and paging. A virtual-mode ListView can be a performance screamer compared to conventional operation over huge data sets. Assuming of course that you can feed it data quickly!


Huge data sets are the main motivation.

Though it is a really poor design practice, some users will insist they need to be able to scroll over entire massive sets of data. What they want is a "giant" grid view of raw data. Since ListView controls work best in report view when in virtual mode, this is the most likely use case for them.

V50ListView is always in report view.


The Demo

The demo offered here goes beyond that of the 2001 original by showing use with an ADO Recordset returned from a Jet SQL query.

To demonstrate what can be done there are a few silly things shown in it. An item icon is used based on the data in each row, here a happy or sad face is displayed depending on whether a "sale" row was "returned" or not. Every 10th row is indented merely for demo purposes.

This demo project will construct a demo database to use with just one table of 100,000 rows. Because it attempts to make "real looking" data it grinds a bit and can take 30 to 45 seconds to do this step, but the database will be reused on subsequent runs. You can also interrupt database creation and just go on from the point of interruption using the rows written at that point.

You can change a constant at the top of Form1 to create a larger database (500,000 or 1,000,000 rows) but you'll have to wait a little longer.

Name:  sshot1.png
Views: 46
Size:  29.8 KB

Once the ListView is "populated" you can scroll it, use the End, Home, Page UP, Page Down, etc. and see how quickly it can move through the data.

I have also tried a modified version with two V50ListView controls on one form to make sure there are no subclassing collisions, and it seems to work fine:

Name:  sshot2.png
Views: 36
Size:  29.2 KB


Using V50ListView

In the attached archive the V50ListView folder contains the pieces necessary:

  • V50LVSubclasser.bas
  • V50ListView.ctl
  • V50ListView.ctx


Copy those 3 files to your own Project's folder to use them, then add the two modules. There is also a resources subfolder there that holds the V50ListView's ToolBoxBitmap image, but of course that's already embedded in the .ctx file so your new Project doesn't really need it.

In order to detect whether it is running at design-time early enough a small hack is also needed. You can put this into your Project's startup Form:

Code:

Private Sub Form_Initialize()
    V50LVSubclasser.UserMode = True
End Sub

Or if you have a startup Sub Main() you can set this global Boolean there instead.

The ItemDataRequest event and the Items property are key here. Setting Items to the number of rows to be displayed causes V50ListView to start raising the ItemDataRequest event to get data to display.

Hopefully the demo Form1 code is enough to help you see how the ItemDataRequest parameters are used to set text, small icons, and indents.

As it stands you also need to associate the ImageList at runtime if you use small icons. Normally you can do this via the design-time Properties window or the Property Pages of the ListView but I haven't implemented that yet. But most people won't be using many V50ListView controls and often won't need icons anyway. However you can just use something like:

Code:

Private Sub Form_Load()
    Set V50ListView1.SmallIcons = ImageList1
End Sub


Caveats

Any subclassing poses risks during IDE testing. If you wish you could revert to the Dbgwproc.dll technique to make breakpoints a little safer to use.

A good solution might be to move V50ListView into a separate ActiveX Control (OCX) Project and compile it. Then during testing of your main Project use the compiled OCX, and when creating a final production version remove the reference and add the two modules to compile it into the program.


Running the Demo

You might compile it first and run the EXE. This speeds database creation a little bit. ;)

Otherwise it runs fine in the IDE.
Attached Images
  
Attached Files

Viewing all articles
Browse latest Browse all 1448

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>