Jump to content

Single Cell Navigation in ListView

Recommended Posts

This example is about Single Cell Navigation in a listview with mouse and keyboard. By default, listviews only supports navigation through the rows. The purpose of this UDF is also to support navigation through the cells.

The UDF supports all four types of listviews: The conventional (all examples in the help file), virtual (includes the $LVS_OWNERDATA style), ownerdrawn (includes the $LVS_OWNERDRAWFIXED style) and ownerdrawn+virtual listview. However, the 7z-file at bottom of post only contains examples for conventional and virtual listviews.

This is the Virtual\Resizable2.au3 example. Run the example in SciTE with F5. Right-click listview and select "Single cell navigation":


The yellow cell is the active cell that is subject of keyboard navigation.

Mouse navigation: Click a listview cell.

Vertical keyboard navigation: Up, Down, PageUp, PageDown, Home and End.

Horizontal keyboard navigation: Left, Right, CapsLock + PageUp, PageDown, Home or End.

If the yellow active cell is located outside the visible page in the listview (if eg. a scrollbar has been used), using a navigation key will again place the active cell on the visible page.

CapsLock is used for horizontal navigation because both Shift and Ctrl are used for standard multiple row selection. CapsLock + PageUp, PageDown, Home or End is especially interesting for ownerdrawn+virtual listviews that supports many columns.

Horizontal or vertical navigation one page at a time can generate a lot of flicker. To prevent excessive flicker, automatic repeat of the PageUp/PageDown keys is disabled.

A large amount of code is used to ensure that when a cell in a only partially visible (or not visible at all) column along a listview edge becomes the active cell, then the entire column and thus the cell becomes fully visible.

Both in the UDF and in the examples, a large amount of code has also been used on the topic of GUI and listview resizing.

For a large control like a listview, it's usually valuable that both the GUI and the listview are resizable. And for a listview, it's nice if the height always fits an integer number of rows.

If a column is made wider or narrower by dragging the header divider so that the horizontal scrollbar appears or disappears, then the height of the listview must be adjusted a little so that it again corresponds to an integer number of rows.

The UDF to some extent support resizing in relation to these assumptions. But only for a single listview. If you need multiple listviews in the same GUI that all offers single cell navigation, then disable resizing in single cell navigation mode (remove resizing in GUI style and remove column resizing in listview header style (Virtual\Resizable4.au3)). Then you can handle resizing completely in your own code.

Implementing the functionality described above already requires quite a lot of code. In order not to use too much code, the following requirements for a listview must be met in order to use the UDF:

  • The $LVS_EX_HEADERDRAGDROP style (drag/drop reordering of columns) is not supported.
  • Zero-width columns are not supported. In the code it's checked that columns are not narrower than 10 pixels.

The code
The code is based on the KeyboardNavigation and MarkCurrentCell examples in the multi-column listviews thread. And these examples are again based on this old example of cell editing.

In the new thread here, the Single Cell Navigation (SCN) functionality is implemented as a UDF in Includes\GuiListViewSCN.au3. The UDF contains two functions to enable and disable SCN functionality. In addition to the usual housekeeping code, the functions starts and stops two message handlers implemented through the subclassing technique that takes care of the actual Single Cell Navigation. One message handler, SCN_GuiHandler(), takes care of WM_NOTIFY messages (listview and header notifications and messages) sent to the main GUI. The other message handler, SCN_ListViewHandler(), takes care of mouse and keyboard messages sent directly to the listview.

Because the code is very much about message handling, Windows Message Monitor has been an important tool for developing the UDF.

Run all examples in SciTE with F5.

Virtual listviews
FirstTest.au3, Incompatible.au3, MultipleLists.au3 and Non-Resizable.au3 are all non-resizable. And it's not possible to change column widths.

FirstTest.au3 is a very simple example that immediately starts up in single cell navigation mode.

Non-Resizable.au3 is similar to FirstTest.au3, but single cell navigation can be enabled/disabled dynamically through the listview context menu.

Incompatible.au3 is incompatible with single cell navigation due to the $LVS_EX_HEADERDRAGDROP style. An error is generated when you right-click to enable single cell navigation.

MultipleLists.au3 demonstrates how to use single cell navigation in multiple listviews. Right-click listviews to enable/disable single cell navigation.

In Resizable1.au3, the width of GUI and listview corresponds to the width of the columns. If you increase/decrease the width of a column or the width of the GUI a little bit, the horizontal scrollbar will appear/disappear.

Resizable2.au3 is the example shown above. It's used to test horizontal navigation.

Resizable3.au3 demonstrates how to handle resizing when the GUI contains more controls than just the listview.

Resizable4.au3 shows how to disable resizing in single cell navigation mode. Then you can handle all resizing in your own code.

Conventional listviews
The examples for conventional listviews are similar to the examples for virtual listviews with the same names.

Single cell navigation can be used for many different purposes. Here it'll be used to implement Rectangular Selection in ListView.

The 7z-file contains source code for UDFs and examples.

You need AutoIt 3.3.12 or later. Tested on Windows 7 and Windows 10.

Comments are welcome. Let me know if there are any issues.


Edited by LarsJ

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Create New...