Vista Command Link Control with C# / Windows Forms
I'm pretty sure all of you, who are using Windows Vista, have come along this new control:
It's called "Command Link" and it is used across many of the new wizards and dialogs included for Windows Vista. I was wondering how to include such controls in an own Windows Forms application (as for WPF I could just simply template a button).
While researching, I found out, that this command-link-button is a simple Win32 button restyled with a new button style (BS_COMMANDLINK). As Windows Forms buttons also wrap classic Win32 buttons, it is possible to restyle one of these for a command link button.
All you have to do is set the FlatStyle of the button to System and apply the BS_COMMANDLINK style to the Style property of the CreateParams of the button.
public class CommandLink:Button
{
const int BS_COMMANDLINK = 0x0000000E;
public CommandLink()
{
this.FlatStyle = FlatStyle.System;
}
protected override CreateParams CreateParams
{
get
{
CreateParams cParams = base.CreateParams;
cParams.Style |= BS_COMMANDLINK;
return cParams;
}
}
}
This will produce a basic command link, as shown above, including a text, but now description. To set a description text, you've got to send a special button WindowMessage BCM_SETNOTE:
SendMessage(new HandleRef(this, this.Handle),
BCM_SETNOTE,
IntPtr.Zero, "Note text");
Getting the content of the note text requires to messages BCM_GETNOTELENGTH, returning the length of the note, and BCM_GETNOTE, querying n+1 characters of the note text.
int length = SendMessage(new HandleRef(this, this.Handle),
BCM_GETNOTELENGTH,
IntPtr.Zero, IntPtr.Zero) + 1;
StringBuilder sb = new StringBuilder(length);
SendMessage(new HandleRef(this, this.Handle),
BCM_GETNOTE,
ref length, sb);
return sb.ToString();
Finally you can also switch the default icon of the command link to a shield, to indicate an administrative operation.
To establish this, you can also use a message, BCM_SETSHIELD (but you have to remember the current value of it, as there is no BCM_GETSHIELD,..)
SendMessage(new HandleRef(this, this.Handle), BCM_SETSHIELD,
IntPtr.Zero, true);
I created properties to wrap these two messages, and packed it all up into a custom WinForms control! With this, all you need to do is drop a CommandLink into your form and set the properties to create forms like this:
Feel free to download the CommandLink control source included as attachment!
Comments
Anonymous
March 11, 2007
The Winforms wrapper is "old" :) I keep getting questions about a WPF version. If you do create a publicly shareable one, let me know so I can link to it from my blog.Anonymous
March 12, 2007
There IS a shareable WPF version of the Command Link: You just need to leverage the "Vista Bridge" Library, which is part of the Windows SDK!Anonymous
March 12, 2007
The comment has been removedAnonymous
March 13, 2007
I agree with you, I'd also expected more managed integration! But anyway the .NET 3.0 is a BIG new MANAGED part in Windows Vista ("unfortunately" it is also available on XP, win2k3 so that doesn't count full). And to be honest, Command Links for instance (although unmanaged) aren't that hard to implement!