.NET Outlook Style ListBar Control
A sophisticated, extensible, easy to use reproduction of the Microsoft Outlook Bar
The .NET ListBar control aims to provide the most accurate reproduction of the Microsoft Outlook bar control. All the features of the Outlook bar control are supported and more: in particular the control provides nicer drag-drop operation, has more display modes and provides an extensible object model which enables it to be used as the basis for more esoteric ListBar style controls.
A .NET ListBar
If you have visited the site before, you may well have seen the VB Classic ListBar control which went so far as to emulate the implementation of the real Outlook control that it used the same underlying controls and window structure. As noted in the article accompanying that control, despite the apparent ease of doing this it wasn't in fact even close to being easy. Therefore this time I took my own advice and started from scratch and implemented everything in Managed Code. Well, almost everything: in-place editing of items and groups requires some Windows API trickery to ensure the edit box is cancelled at the right time. The method used to achieve this, and how to remove it from the control if a 100% managed version is needed, is described later in the article.
Tear-Stained Pillows and Broken Shot Glasses
The consequences of this decision were much less trouble with the under-documented and often incomprehensible ListView API and instead much greater trouble at my own inability to achieve simple tasks such as visualising the trivial two-dimensional transformation of a scrollable view without using a ruler and a model constructed from scraps of paper. Luckily the ready availability of Bison Grass vodka, pressed apple juice and Autechre's Draft 7.30 mean that the .NET control is now finally available, and it is guaranteed not to have the positioning/items disappearing problems which afflicted the earliest releases of the VB version.
About The Downloads
There are three downloads provided with this article.
Using The Control
The object model of the ListBar control is shown in the diagram below:
You should find the object model fairly self-explanatory: full documentation of all of the methods and properties of the control are provided in standard form in the downloads, courtesy of NDoc. However here's a quick-start tutorial on setting up a control.
Reusable Code Components
The source code for the control also some code which can be extracted and reused for other projects.
The CustomBorderColor class
This class uses the HLS class to create shadow and highlight colours like the ones Windows produces for the 3D object colour for any arbitrary colour.
A method is also provided to draw a thin or thick border using the custom colours.
The PopupCancelNotifier Component
This component is designed to allow you to detemine when a popup object (like the item caption edit text box in the ListBar control) should be cancelled due to the user clicking somewhere else in the control, or otherwise changing focus. This is the area of the control which uses Unmanaged Code; I do not believe it is possible to achieve this in any other way. The problem which occurs with the popup object is as follows:
If the user clicks somewhere else on the form, the only event which can occur in the control or the popped-up object is LostFocus. However, this only fires if the user clicks on something that can get keyboard input focus - and many .NET objects do not so no event is fired. If the user Alt-Tabs to another Window then the .NET Framework assumes the focused control should not change and again you don't get an event.
The PopupCancelNotifier component works around these issues. It does two things to ensure a popup object is cancelled at the right time: firstly, it installs a Windows Mouse Hook to detect any mouse button presses within the control and secondly it subclasses the form which owns the popup object to check for WM_ACTIVATE Windows messages, which are sent whenever a window is activated or deactivated.
Using this component is simple: create an instance of PopupCancelEventHandler and call the StartTracking method, passing in the Form which owns the control you've popped up (or the Form itself if you're popping up a form). The OnPopupCancel method will be called, raising the PopupCancel event if the item needs to be cancelled, otherwise call the StopTracking method when you're done.
Creating a 100% Managed ListBar Control
It is possible to create a version of the ListBar control that is 100% Managed Code, however, this means that in-place editing of labels must be removed. To do this, remove PopupCancel.cs from the control and then comment out all methods which refer to it and the StartEdit methods of the ListBarGroup and ListBarItem classes. The resulting code will work almost be exactly the same as before but if you want the user to be able to edit item or group captions you will need to provide an alternative UI (for example, a modal dialog).
This article provides a fully-documentated Outlook-style ListBar control for the .NET Framework. The current implementation includes some Unmanaged code but this can be compiled out if desired.