Welcome to CrankyGoblin.Com Sign in | Join | Help

Public Class GeoffAppleby

Inherits Microsoft.VisualBasic.MVP : Implements IBrainFart
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 :)

Posted: Sunday, June 25, 2006 6:21 PM by Geoff Appleby
Filed under: , ,

Comments

Thomas Williams said:

Hey Geoff - nice control!

I have been looking for a replacement "verbose" messagebox-like control (after having slightly updated my current .NET 1.1 to 2.0, but still not happy with the functionality), and yours is now top of the list.

Well done - the "Vista" look is cool (even the image hack on the "Cancel" button). The ability to set & retrieve DialogResults on the CommandLinks is nice. You have left yourself room to have a display style of "DisplayStyle.Custom" with a custom icon.

I've got some possible, yet minor, improvements:
* keyboard support: tab, enter (i.e. to select "default" button if one is marked)
* focus rectangles on command links (does Vista have them when tabbing?)
* improved focus rectangle on cancel button
* tooltips?

Cheers,

Thomas
# June 26, 2006 11:59 PM

Geoff Appleby said:

Hey Thomas,

Thanks for the feedback, and I'm glad you liked it :)

keyboard support - Definately on my list.
focus rectangles - Now on my list.
improved button focus - I've never even considered looking at overriding the focus rectangle. I'll have to look into it :)
Tooltips - yup, already on my list.

I'll have to have a play with what the keyboard support is like in vista for these. It should be fine, given that commandlinks are just buttons anyway. To stop the (currently) ugly focus rectangles appearing on the commandlinks, i've set them to tabstop=false for the moment, but I want to look into that.

I've made some other assorted improvements already that i'll be releasing probably over the weekend, when I release my TiledListView that i finished earlier this week.

One thing that I know very little about is custom painting.  I've noticed moving the mouse around quickly (over several links at once) makes the painting slow down. If there's some way to speed it up, i'd love to hear about it.

Maybe WPF is the way to go :)  But I haven't learned much about it yet *laughs*
# June 28, 2006 6:29 PM

Daniel Moth said:

CommandLink for XP

# September 28, 2006 2:28 AM

Mike Scott said:

Geoff,

I have been looking for a neat way to implement Vista CommandLinks in XP for a while before I happened to find your blog. It looks like you share my appreciation of getting a clear and easy to use UI. And you have done a great job at implementing it.

If it is alright with you, I would like to include some of your code in an app I'm writing at the moment. I just wanted to check that this was OK with you before I "infringed your copyright".

Cheers,

Mike

# March 5, 2007 8:03 AM

Geoff Appleby said:

Go for it.

# March 5, 2007 11:43 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

To submit your comment, click on these pictures:
  • Geoff's tongue
  • Teenage Mutant Ninja Geoffy!
  • Geoff's bald spot
Gaptcha Image - No Peeking! Gaptcha Image - No Peeking! Gaptcha Image - No Peeking!
Gaptcha Image - No Peeking! Gaptcha Image - No Peeking! Gaptcha Image - No Peeking!
Gaptcha Image - No Peeking! Gaptcha Image - No Peeking! Gaptcha Image - No Peeking!
Can't recognise the people in these pictures? Look here for a quick introduction.
There's a time limit for you to get your comment submitted before this set of pictures expires. If you think it's been longer than 10 minutes, get some new pictures first (you won't lose what you've typed so far).
Get some new pictures 

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS