NSListView ActiveX control


1. Overview

The NSListView objects
Object model diagram
General notes and remarks

2. Objects reference:

NSListView, ListItems, ListItem, SubItems, SubItem, Columns, Column, ColumnItems, Results

3. Using NSListView control

1. Overview and architecture

The NSListView control exposes the Windows ListView control for the NSBasic applications. For that purpose it has internal object structure in which every ListView element is exposed to the application as an object with appropriate methods and properties. 

ContentsQuick links: NSListView object diagram, General notes, Using NSListView

The NSListView objects

The example lines below assume you have AddObject "NSBasic.comctl.ListView", "MyListView", ...

NSListView The root object which represents the control as whole.
example: MyListView.LabelEdit = True
    Columns A collection that holds the columns of the ListView control in report view
example: colcount = MyListView.Columns.Count
        Column Represents a column in report view
example1: MyListView.Column(2).Text = "Size (kbytes)"
example2: MyListView.Column("Size").Text = "Size (kbytes)"
            ColumnItems A collection of all the items/subitems in the column
example1: MyListView.Column(2).ColumnItems(5).Text = "20k"
example2: MyListView.Column(2)(5).Text = "20k"
    ListItems A collection of all the items (rows in report view) in the ListView
example: itmcount = MyListView.ListItems.Count
        ListItem Represent individual item (row in report view).
example1: MyListView.ListItems(5).Text = "Item 5"
example2: MyListView(5).Text = "Item 5"
example3: MyListView("MyItem5").Text = "Item 5"
            SubItems A collection of all the subitems of the item in report view
example: colcount = MyListView.ListItems(5).SubItems.Count
                SubItem Represents a subitem object in report view
example1: MyListView.ListItems(5).SubItems(2).Text = "20k"
example2: MyListView(5)(2).Text = "20k"
    Font The font settings for the control (apply to everything) (NSFont object)
example: MyListView.Font.Bold = True
    Icons List of the images used in Icon view (NSImageList object)
example: MyListView.Icons.LoadBitmap "\MyBitmap.bmp"
    SmallIcons List of the images used in SmallIcon and report view (NSImageList object)
example: MyListView.SmallIcons.LoadBitmap "\MyBitmap.bmp"
    ColumnHeaderIcons List of the images used in the column headings in report view (NSImageList object)
example: MyListView.ColumnHeaderIcons.LoadBitmap "\MyBitmap.bmp"

The NSListView object model diagram

Click on the object of interest to go to the page describing it.

NSListView general notes and remarks

The control's architecture may look complex at first, but in fact the usage of the control is quite simple. Each element is accessible through an object named after the element it represents thus enabling you to write code without checking the documentation for each line you write. To help you follow the naming convention the ListView terminology is listed below. The same terminology is used in MSDN and the documentation of other ListView ActiveX controls - if you have ever used one you will find it familiar.

Item - The ListView is a linear collection of items which consist of image, text, state, tag and other data (See also the views below)
Column - (visible in report view only) is a column which may have or not have a heading. The items and their subitems are listed in columns.
SubItem - (visible in report view only) each item may have subitems - one per each column currently visible in the control.
View - 4 views are supported by the control: Icons (sometimes referred as big icons), Small icons, List and Report. The Report view is the most complex one and offers grid-like functionality. NSListView is especially designed to simplify grid-like usage.

The views

Icon view (big icons).

The images from the Icons image list are used, the item text is displayed under the image. If checkboxes are enabled they appear on the left of the image.

Small Icons view

Much like the Icon view but the images from the SmallIcons image list are used and the item text is displayed on the right. If checkboxes are enabled the checkbox appears on the left side.

 

List view

Although similar to the Small Icons view in List view the items are listed sequentially in columns from left to right. The images from the SmallIcons image list are used.

Report view

The images from the SmallIcons image list are used. The items are listed vertically in the first column (unless the column order is changed by the application) and the other columns display the corresponding SubItem of the item. If you think of the items as rows you can think of the first column as of rows headers and for the SubItems as cells of a table.

All the Items, columns and SubItems can be accessed, changed and otherwise managed no matter the current view. However the columns and the sub items will be visible only in report view.

2. Objects reference

NSListView

Represents the NSListView control. Exposes general properties and the objects that control the internal elements of the control.

Members reference

Name Syntax Description
Objects
Columns Set cols = object.Columns Returns the Columns collection. It contains all the columns in the control.
alias: ColumnHeaders
ListItems Set items = object.ListItems Default. Returns the ListItems collection which contains all the items (ListItem objects) in the control.
Icons Set icons = object.Icons NSImageList containing the large icons, which are displayed with the items in the Icon view.
By default this image list is initialized with size 32x32
SmallIcons Set icons = object.SmallIcons NSImageList containing the small icons, which are displayed with the items in the all the views other than Icon view. The same list is also used when images are displayed with the sub-items.
By default this image list is initialized with size 16x16.
ColumnHeaderIcons Set icons = object.ColumnHeaderIcons NSImageList containing the icons, which are displayed on the column headers.
By default this image list is initialized with size 16x16.
Font Set fnt = object.Font Contains NSFont object that specifies the font used everywhere in the control.
View and behavior 
AllowColumnReorder object. AllowColumnReorder = b
b = object. AllowColumnReorder 
Enables (True)/Disables (False, default) the user to reorder the control's columns in report view by dragging them with the mouse or the stylus.
View object.View = v
v = object.View 
Puts/Gets the current view mode of the control:
0 - (default) Icon view (big icons)
1 - Report view
2 - Small icons view
3 - List view
HideSelection object. HideSelection = b
b = object. HideSelection
Boolean. Default is True. If set to false the selection in the control is indicated also when the control does not have the focus.
MultiSelect object.MultiSelect = b
b = object.MultiSelect 
Boolean. Default is True. When set to False only one item can be selected at a time.
Enabled object.Enabled = b
b = object.Enabled 
Enables/Disables the control.
Arrange object.Arrange = a
a = object.Arrange 
Integer constant. Specifies how to arrange the items in the control in Icon and Small Icons view only. Has no effect in the other view modes.
HideColumnHeaders object. HideColumnHeaders = b
b = object. HideColumnHeaders 
Boolean. Default is False. If set to True the column headings are hidden in report view.
LabelEdit object. LabelEdit = b
b = object. LabelEdit 
Boolean. Default is False. If set to True enables the user to invoke label editing for items by "slow" double click or pressing F2.
LabelWrap    
Checkboxes    
FullRowSelect    
SubItemImages    
TrackSelect    
UnderlineCold    
UnderlineHot    
SortHeaders    
GridLines    
BackColor    
TextBackColor    
TextColor    
Operations, sorting and so on
FindItems Set results = object.FindItems( _
    text, _
    [subitems], _
    [tags], _
    [partial])
Searches through the items and (optionally) the sub-items in the control. Returns a collection of the items and sub-tiems that match the criteria.
Arguments:
text - String. Text to search
subitems - (optional) Boolean. If True both the items and the sub-tiems are searched, default is False
tags - (optional) Boolean. If set to True the search is over the value of the item's/sub-item's Tag property and not the Text property. Default is False.
partial - (optional) constant:
    0 - (default) exact match
    1 - partial (match if the string starts with the searched text)
    2 - substring (match if the searched text can be found somewhere in the value)

Returns: a Results collection containing the ListItem and SubItem objects that match the criteria.

UnSelectAll object.UnSelectAll De-selects all the items in the control.
SelectedItems Set results = object.SelectedItems Returns a Results collection containing all the currently selected items (ListItem objects)
SetFocus object.SetFocus Sets the keyboard focus to the control. Aside of the obvious usage you may need to call this method when you use on your form a control that gets the focus implicitly after certain operation.    
SortOrder object.SortOrder = v
v = object.SortOrder 
Integer constant. Specifies the sort order in the control:
0 - (default) ascending
1 - descending
Assigning a value (even reassigning the same) causes resort. 
Sorted    
SortKey    
Tag    

 

ListItems collection

A collection that contains all the items (ListItem objects) in the control

Syntax:

NSListView.ListItems

Members reference

Name Syntax Description
 
Add [Set itm =] object.Add(
    [Index],
    [Key],
    [Text],
    [Icon],
    [Indent])
Adds a new item (ListItem object) to the control. All the arguments are optional, they are:
Index - integer specifying the index for the new item 1 - based. If omitted the item is added as last item.
Key - String, the key name for the item. If specified the created ListItem object can be accessed later by name.
Text - The text label for the new item.
Icon - Image index or name in the image list applicable to the current view (Icons in Icon view, SmallIcons in all the other cases). 
Indent - Specifies the indent of the item in report view. See ListItem.Indent
Clear object.Clear Removes all the items.
Count c = object.Count Integer. Returns the count of the items.
Item Set itm = object.Item(x)
Set itm = object(x)
Default. Returns the indexed item (ListItem object).
x - is integer 1-based index or Key name of an item. If more than one item has the same Key the first is returned.
Remove object.Remove x Removes the indexed item (ListItem object) from the control.
x - is integer 1-based index or Key name of an item. If more than one item has the same Key the first is removed.
ListView Set NSListView = object.ListView Returns reference to the NSListView control to which this object applies

Remarks:

ListItem object

Represents an item in the control.

Syntax:

Set itm = NSListView.ListItems.Item(index)
or
Set itm = NSListView.ListItems(index)
or
Set itm = NSListView(index)
or
Set itm = NSListView("key")
or
For Each itm In NSListView.ListItems
   ' make use of itm
Next

 

Members reference

Name Syntax Description
 
SubItems    
 
EnsureVisible    
StartLabelEdit    
Checked    
Icon    
Index    
Key    
Selected    
Tag    
Indent    
Text    
 
ListItem    
IsSubItem    
ListView    

Remarks:

Columns collection

A collection that contains all the Column objects in the control

Syntax:

NSListView.Columns
or
NSListView.ColumnHeaders

 

Members reference

Name Syntax Description
 
Add    
Clear    
Count    
Item    
Remove    
 
ListView    

Remarks:

Column object

Represents a particular column in the control.

Syntax:

Set col = NSListView.Columns(index)
or
Set col = NSListView.ColumnHeaders(index)
or
Set col = NSListView.Columns("key")
or
Set col = NSListView.ColumnHeaders("key")
or
For Each col In NSListView.Columns
   ' make use of col
Next

 

Members reference

Name Syntax Description
Objects and collections
ColumnItems Set o = object.ColumnItems A collection of all the items or subitems in the column. If this is column 0 the elements are Item objects, if this is column 1 or greater the elements are SubItem objects.
Properties and methods
Alignment    
Icon    
Index    
Key    
Position    
SortType    
SubItemIndex    
Tag    
Text    
Hierarchy properties
ListView    

Remarks:

ColumnItems collection

A collection that contains all the SubItem objects in the Column to which this object belongs

Syntax:

NSListView.Columns(index).ColumnItems

Members reference

Name Syntax Description
 
Count    
Item    
Enumerator    

Remarks:

SubItems collection

A collection that contains all the SubItem objects of the Item to which this object belongs.

Syntax:

NSListView.ListItems.Item(index).SubItems
or
NSListView(index).SubItems

Members reference

Name Syntax Description
 
Clear    
Count    
Item    
ListItem    
ListView    
Remove    
 
DefinedCount    
ItemByIndex    
RemoveByIndex    

Remarks:

SubItem object

Represents a sub item in the control.

Syntax:

Set subitm = NSListView.ListItems.Item(index).SubItems(subindex)
or
Set subitm = NSListView.ListItems.Item(index)(subindex)
or
Set subitm = NSListView(index)(subindex)
or
Set subitm = NSListView.ListItems(index).SubItems(subindex)
or
Set subitm = NSListView(index).SubItems(subindex)
or
Set subitm = NSListView.ListItems(index)(subindex)
or
For Each subitm In NSListView(index).SubItems
   ' make use of subitm
Next
or
For Each subitm In NSListView.Columns(index).ColumnItems
   ' make use of subitm
Next

 

Members reference

Name Syntax Description
 
Icon    
Index    
IsSubItem    
Key    
ListItem    
ListView    
Tag    
Text    

Remarks:

Results collection

Represents a collection of objects returned as result of a search or other operation. The type of the objects in the collection depends on the operation.

Syntax:

Set result = NSBImageList.FindItems("search what",True)
or
Set result = NSBImageList.SelectedItems

Members reference

Name Syntax Description
 
Count c = object.Count Returns the number of the elements in the collection. 
Item Set itm = object.Item(Index) Default, indexed property. Index is 1 based integer index.
Enumerator For Each itm in object
...
Next
Cycles through all the elements of the collection. 

Remarks:

3. Using NSListView ActiveX control

The NS BASIC ListView control is easy to use despite the number of the objects in it. Their actual purpose is to represent each element in the control i a convenient way and thus enable you work with it in intuitive way. 

The ListView is a control that can be used in various ways - it can present simple pictured list of items with text labels, but it can also work like a table/grid and display data in columns with sorting and other extras. Furthermore the control can expose all the items in it as checkboxes, the items (in report/grid view) can be indented and the control may become quite similar to a tree view. All this makes it the control of choice for many tasks. Depending on the application the control can be pre-configured for a certain view only (e.g. as a grid or as icon view), but sometimes it is convenient to enable the user to change between 2 or more views. The classic example is the Windows Explorer in which the files can be viewed as big/small icons or in a report view with detailed information about the file in each row.

So, where to begin? We will begin with a simple icon view in mind, but we will then move to a report view. One of the most important features of the control is that all the elements are accessible and creatable no matter if the current view shows them or not. For example you can perform tasks that will fill information for the report view while the list is shown as icons - the data you add in the sub items will not be visible until the view is changed to report. This means that the application can always assume that the control is in report/grid view and manage its contents in this manner. So, if the task the application is performing deserves a report view you can think in its terms no matter if it is allowed to change the way the user views the data (thus hiding/unhiding parts of it when the view is changed).

Lets start: We assume we have a form (Form1) and a NSListView control is added to it under the name NSListView1 (see how to add the control to the toolbox). 

Let's add a few items for a start:

NSListView1.ListItems.Add 1,"Item1 Key","My item 1"
NSListView1.ListItems.Add 2,"Item2 Key","My item 2"
NSListView1.ListItems.Add , ,"My item 3"

We add the items through the ListItems collection. The control has many elements and that is why we need to be specific (For example we may add also columns or images).

All the arguments of the ListItems.Add method are optional, thus (in the 3-d line above) we decided to omit most of the item parameters. This is what the control will look like after these lines
:

There are no icons? Well, lets load some:

NSListView1.Icons.LoadBitmap "bigicons1.bmp"
' note that you may need to specify the full path to the bitmap in the real world

By default the items use the first icon from the loaded image. The image we loaded above actually looks like this:

The image list is a collection of images all with the same size. When a bitmap is loaded it expects there 1 or more images of the size currently configured. The images are to be ordered from left to right in the bitmap. By default the Icons image list is configured for 32x32 pixel images.

Now lets change the item images:
NSListView1.ListItems("Item1 Key").Icon = 1
NSListView1.ListItems("Item2 Key").Icon = 2
NSListView1.ListItems(3).Icon = 3

Above we have set keys for some of the items. This means that we can do the same this way:

NSListView1.ListItems(1).Icon = 1
NSListView1.ListItems(2).Icon = 2
NSListView1.ListItems(3).Icon = 3

So, the keys can be used as item name which can be specified instead of an index. This can be quite useful when the data in the control has no definite order.

Let's now do all this again, but  in much simpler way - saving some typing work:

NSListView1.Icons.LoadBitmap "bigicons1.bmp"
Set itm = NSListView1.ListItems.Add(1,"Item1 Key","My item 1")
itm.Icon = 1
Set itm = NSListView1.ListItems.Add(2,"Item2 Key","My item 2")
itm.Icon = 2
Set itm = NSListView1.ListItems.Add( , ,"My item 3")
itm.Icon = 3

The Add method returns the just created item, thus giving us chance to do something more with its properties. We can also use the rest of the optional parameters of the Add method and eliminate the need to specify the item's image on a separate line:

NSListView1.ListItems.Add 1,"Item1 Key","My item 1", 1
NSListView1.ListItems.Add 2,"Item2 Key","My item 2", 2
NSListView1.ListItems.Add , ,"My item 3", 3
NSListView1.Icons.LoadBitmap "bigicons1.bmp"

Let's talk about line 3. It does not specify an index for the created item - where it will be put? The answer is it will be appended at the end of the ListItems collection. Thus skipping the index is equivalent to:

NSListView1.ListItems.Add NSListView1.ListItems.Count, ,"My item 3", 3

Therefore when we add the items sequentially or the order does not matter to the application we can just skip the index.

Now suppose we want to cycle through all the items and extract some information from them. For the example we will use their Text property. We can do this in two ways:

' Normal cycle
For I = 1 to NSListView1.ListItems.Count
  MsgBox NSListView1.ListItems(I).Text
Next

or

' Enumeration
For Each I In NSListView1.ListItems
  MsgBox I.Text
Next

Which way is better? Actually neither is better than the other, the latter needs a bit less code, but aside of that all depends on any other needs that you may have. The second technique is called enumeration. The control exposes enumerations in many places - for the items, for the columns, for the sub items of each item, for the items/sub items in each column and so on. Generally the enumeration is more effective especially if you enumerate sub items (discussed below).

Before continue let's change the view. Firs to small icons:

NSListView1.View = 2

Again no icons, what are we missing? All the other views except Icon view use the SmallIcons image list. We have nothing loaded in it yet, so no icons appear in the control. Let's load another bitmap - with smaller images (16x16 by default):

NSListView1.SmallIcons.LoadBitmap "smallicons1.bmp"

the bitmap looks like this:

and the control after the above line:

Now let's switch to report view and see what we can do with the control in its most powerful form.

NSListView1.View = 1

What we see? There is one column with empty caption and all the items are listed one under another in it. The SmallIcons are used. Can we put some caption to that column? Yes:

NSListView1.Columns(0).Text = "Items"

We can also set an icon to that column:

NSListView1.Columns(0).Icon = 1

But remember the columns have separate image list from which their icons are fetched and we have nothing in it yet. so to make the above two lines work we should:

NSListView1.ColumnHeaderIcons.LoadBitmap "smallicons1.bmp"
NSListView1.Columns(0).Icon = 1
NSListView1.Columns(0).Text = "Items"

By default the size of the header icons is 16x16 - the same as for the small icons, but you can change that (discussed later).

What is important about the report view? It looks like a table or let say a grid control. The NSListView is especially designed to make table-like usage convenient and natural. Now is the time to note some characteristics of the NSListView control. If you have some experience with other ListView controls or with the native Windows control (using C for example) it is very likely that you have some troubles especially if you have attempted dynamic changes of the columns and the items. NSListView hides virtually all the sensitive details and you can safely assume the report view a table/grid. To refine the table abstraction let say that the Items we discussed above play the role of rows and the columns are just columns. Thus the first column is special - it cannot be deleted, the items are listed in it, the column can be changed, but it is always present.

That's why the index of the first column is 0 while everything else in the control has 1-based indices. Furthermore the Columns.Count returns only the count of the columns you added without this first column which we will call later column 0. Thus the columns can be assumed to have 1-based indices if you count only the columns you can freely add and delete.

Let's add 3 columns:

NSListView1.Columns.Add , "Column1 Key","Column 1", 50
NSListView1.Columns.Add , "Column2 Key","Column 2", 50
NSListView1.Columns.Add , "Column3 Key","Column 3", 100, 2, 4

If we want to cycle through them we can do it like this:

For I = 1 To NSListView1.Columns.Count
  NSListView1.Columns(I).Text = "My Column " & I
Next

changing their caption text a little. As we said above this cycle will cycle only through the columns we added and will not include the fixed column 0. If we want to include it into the cycle we should change it:

For I = 0 To NSListView1.Columns.Count
  NSListView1.Columns(I).Text = "My Column " & I
Next

Now lets use enumeration instead of an index cycle:

For Each col In NSListView1.Columns
  col.Text = "Column " & col.Index
Next


We end up with something like this

Both cycles do the same work. When working with columns it is more likely that an index cycle will be better choice because for columns we will need more often to know the exact index. However, we shall see later that the enumerations are generally more convenient for almost everything else.

Back to the columns. The Columns.Add method has these parameters:
.Add index, Key, Text, Width, Alignment, Icon
All the arguments are optional, but you must be aware of the specific behavior of the columns about the icons. If no icon is specified when the column is created (added) no icon can be ever set to that column. This behavior of the native Windows control is preserved in the ActiveX for a reason - the icons even empty occupy some space. And this is the only way to get rid of that space. So, if the space in the column's caption is more precious than the opportunity to show icons in the column's header - omit the image argument, but remember that if you assign something to the Icon property of that column nothing will happen. To illustrate that lets cycle through the columns again and try to assign images:

For I = 0 To NSListView1.Columns.Count
  NSListView1.Columns(I).Icon = I - 1
Next

Nothing will change no matter that we actually have 4 icons with indices 1-4. If we change the code with which the columns have been created and specify some initial image the cycle will have effect.

What is the key for? Like with the items it can be used instead of the index:

Set mycolumn = NSListView1.Column("Column2 Key")
will return the same as:
Set mycolumn = NSListView1.Column(2)
because we keyed that column "Column2 Key"

Now let's do something with the cells of the table or in the terms of the list view - the sub items.

(to be continued)