CommandLink Control for XP
I really like the new CommandLink control that exists in Vista. Actually, it's not a new control - it's just a new style on the button control, but it still looks damn nice.
The app we're currently writing at work is being written with with a series of principals in mind, the first being 'make it as dumb as possible, the users of this app are idiots!'.
So I thought I'd take a leaf out of the mandates of Vista's design guidelines (Clear, Concise, Connected) and base a bit of our UI on how Vista is presenting options to the user. This is all well and good, but Vista isn't out yet, and who knows how long it will be until it's actually deployed to our users desktops!
So it's time to start writing some user controls. As I get them done, I thought I'd release them here.
First up is the CommandLink control. The CommandLink control is used to query an action from the user, by presenting a nice descriptive list of their choices. Here's an example screenshot from Vista of this in action:

The one that the mouse is over gets a border drawn around it to show that it's clickable, and the text becomes a lighter color, otherwise it just looks like a long text list (with icons).
So using several screenshots of the above and a fair bit of playing, I've created three controls that, when put together, looks pretty much like the sample up there.
The first is the CommandLink. It's one of the items that can be shown in a list. It has The main properties - Text (which is the first line of text in the CommandLink), Description (which is the next two lines) and Style (which lets you set the icon that appears). It inherits from button just like in Vista, so that you can set the CommandLink as a form's AcceptButton or CancelButton.
The CommandLink is prett limited so far. You can't insert just any image at the moment, only the three I have predefined. If your description text is too long, it'll get chopped at the second line. If your main text is too long, it'll get chopped at the right hand edge. I'll get there one day, but it works for my purposes.
Next is the VistaButton. This is a pretty crappy attempt at emulating how normal buttons look when used with the Aero theme in Vista. I decided to go all out and include the cancel button from the above screen shot :) It's just a normal button but I override the background image depending on the mouse state.
Last is the CommandDialog. Instead of having to render the CommandLinks yourself, the CommandDialog will take a list of CommandLinks and host them then, returning to you whichever one was clicked on. It's main properties are Text (for the title bar, like on any form), Title (for the first line of text) and Description (for the second two lines). It also is pretty limited. You can also hide the Cancel button (and the whole bottom grey panel) by setting the ShowCancelButton property to false. Overriding the CancelButton property of the CommandDialog will also cause the current Cancel button to be hidden.
In all cases, I've hard coded specific sizes and colors and things. What I haven't done is then hidden those properties so that people can't booger them all up. I'll get there one day, but for now, knowing that you only touch it as little as possible, they render quite nicely.
I've also defaulted to using the 'Segoe UI' font, which is what Vista uses. If you don't have that installed, you'll end up with one of your system defaults (Like MS Sans Serif, or something). It won't look as good, but it still renders. I'm not sure where it comes from either - probably the fact that I have Office12 B2 installed :)
The code to get it all going it pretty simple. Create a set of CommandLinks, provide them to the CommandDialog, and call it's ShowDialog() method.
Here's the code for my test app.
Module MainModule
Public Sub Main()
Dim oCommandDialog As New VistaControls.CommandDialog
Dim oCommandLinks As New List(Of VistaControls.CommandLink)
'create our command links
For i As Int32 = 0 To 3
oCommandLinks.Add(New VistaControls.CommandLink())
With oCommandLinks(oCommandLinks.Count - 1)
Select Case oCommandLinks.Count - 1
Case 0
'normal
.Text = "Ask me again later"
.Description = "An ordinary command link has a green arrow for an icon, a title, and some descriptive text."
.Style = VistaControls.CommandLink.DisplayStyle.Arrow
Case 1
'default
.Text = "This is a default command link"
.Description = "To make a command link 'default', set it as the AcceptButton on the CommandDialog form. It has a light blue border around it."
.Style = VistaControls.CommandLink.DisplayStyle.Arrow
Case 2
'shield
.Text = "This is a shield command link."
.Description = "Using this one shows that clicking it will cause some action to be performed that requires admistrative privileges."
.Style = VistaControls.CommandLink.DisplayStyle.Shield
Case 3
'cancel
.Text = "This is a cancel command link."
.Description = "This one can be used as a cancel button, or maybe even as a 'yes, delete this file' button, perhaps."
.Style = VistaControls.CommandLink.DisplayStyle.Cancel
End Select
End With
Next
With oCommandDialog
.CommandLinks = oCommandLinks
.AcceptButton = oCommandLinks(1) ' default
'.CancelButton = oCommandLinks(3) ' cancel
.Text = "Sample Command Dialog"
.Title = "This is Command Dialog"
.Description = "This is a sample command dialog. It has title and description text, and a set of command links."
.StartPosition = FormStartPosition.CenterScreen
End With
'show it, interrogate the result
If oCommandDialog.ShowDialog() = DialogResult.OK Then
Dim oCL As VistaControls.CommandLink = oCommandDialog.SelectedCommandLink
MsgBox("The selected CommandLink was: " & oCL.Text)
Else
MsgBox("The command dialog was closed without selecting a CommandLink")
End If
End Sub
End Module
Here's a shot of the resultant dialog running in XP.
<>
And that's all there is to it!
I'm no UserControl expert. The custom painting can probably be improved, as well as just about every other aspect of each of the controls :) I'm certainly wanting feedback on what I've done wrong, that's for sure.
You can download the full source for this from here. As I make updates or additions, the package will be updated.
Next up, the TiledListView like Vista has :)