Collection Methods and Properties


My biggest beef with list boxes is that although they look and act like collections, they’re not quite collections. For one thing, they’re zero-based instead of one-based. For another, they have the wrong property and method names—ListCount, List, AddItem, and RemoveItem instead of Count, Item, Add, and Remove. Furthermore, they don’t work with For Each.


You can curse the darkness or you can light a candle. I did both. The XListBox­Plus control has one-based collection methods and properties. It looks and works like a collection.


The design of XListBoxPlus is more interesting than its code. This class tries to combine the best features of list boxes and collections, keeping in mind that list boxes can’t work quite the same way as collections work. The biggest difference is that list boxes have a selected item, and collections don’t. Other ­differences are simply limitations of list boxes—limitations that XListBoxPlus ­attempts to eliminate. Table 11-1 compares what you can do with a list box, a collection, and a sorted list box (represented by lst, n, and srt, respectively).

Operation ListBox Collection XListBoxPlus
Get item 3 s = lst.List(2) s = n.Item(3) s = srt.Item(3)
Get "Pig" index Can’t do it Can’t do it i = srt("Pig")
Select "Pig" lst.Text = "Pig" Undefined srt.Text = "Pig"
srt.Current = "Pig"
Change item 3 lst.List(2) = "Dog" Can’t do it srt.Item(3) = "Dog"
Change "Dog" Can’t do it Can’t do it srt("Dog") = "Cat"
Select item 3 lst.ListIndex = 2 Undefined srt.Current = 3
Get index i = lst.ListIndex Can’t do it i = srt.Current
Get selected s = lst.Text Undefined s = srt.Text
Add "Cat" lst.AddItem "Cat" n.Add "Cat" srt.Add "Cat"
Remove item 3 lst.RemoveItem 2 n.Remove 3 srt.Remove 3
Remove "Pig" Can’t do it n.Remove "Pig" srt.Remove "Pig"
Iterate by item Can’t do it For Each v in n For Each v in srt
Iterate by index For i = 0 To _ For i = 1 To _ For i = 1 To _
lst.ListCount –1 n.Count srt.Count


Table 11-1. List box and collection operations.


Most of these operations are clear once you understand list boxes and collections, but a few bear further study. I programmed with list boxes for years before I understood two of their more useful, but obscure, features. I knew that the Text property was important for combo boxes, but I didn’t know it even existed for list boxes. I always wrote this redundant code to access the selected item:

s = lst.List(lst.ListIndex)

Every time I wrote it I cursed the authors of the ListBox control for requiring such an ugly syntax, and I took a little jab at them in the first edition of this book. Well, I like my crow with catsup. Here’s what you can do instead:

s = lst.Text

The Text property can also be used to look up an item. (Yum! Feathers and all.) You can select the Crow item with this syntax:

lst.Text = "Crow"

If there is no Crow item, you’ll deselect whatever is currently selected (ListIndex = –1). The lookup is case insensitive (crow finds Crow), but complete (Cro doesn’t find Crow).


This is cool, but the XListBoxPlus is even more so. You can index by number or by string value. It works kind of like collections, but

i = n("Pig")

and

i = srt("Pig")

don’t mean exactly the same thing. Indexed collections return objects, as explained later in this chapter in “Sorted Collections,” but sorted list boxes contain strings, not objects. Indexing has to mean something different.


I made the default Item property return a numeric index if you pass a string, or a string if you pass an index. Purists might object to a property returning different types for different arguments, but it works in this case.


Here are few other points for users of the XListBoxPlus class: