Charles Petzold

Label (and Button) Mnemonics

January 6, 2006

JFo and Richard Bailey have been discussing underline mnemonics on Label controls in WPF. The underline mnemonics also work with text set in menu items and buttons.

Both Button and Label derive from ContentControl, which defines an all-important property named Content of type object. The Content property is what actually appears in the Button or Label. If you set Content to an instance of any class that derives from UIElement, the content will be rendered graphically using the class's OnRender method. Otherwise, the Content object is displayed with ToString. (MenuItem derives from HeaderedItemsControl, but the Header property plays basically the same role as Content.)

For simple traditional buttons, you set the Content property to a string, and that's what shows up in the button. The string can optionally contain an underline character for a mnemonic. Pressing Alt and the underlined letter triggers the button.

If you want to mix text and graphics in a button, you need to set the Content property to a panel of some sort, and then put the text and graphics on that panel. Do you lose the mnemonic feature in that case? Not at all. The trick is this: If you include a Label control among the stuff you put on the button, then the label can have an underlined mnemonic and the button will respond to it.

I have a program from Part 1 of my forthcoming book Applications = Code + Markup that demonstrates this technique. Here's DesignAButton.csproj, DesignAButton.cs, and BOOK06.ICO, an icon file among the collection shipped with Visual Studio 2005. The program puts a StackPanel on a button, and then adds a Polyline, an Image based on the icon, a Label with an underlined letter, and another Polyline. And, as promised, clicking the label mnemonic (Alt-R) triggers the button.

I've tried deeper nestings of the Label within Button content, and it seems to work just fine. (If there's anything we know about WPF, it's an assurance that there's lots of recursive code in there.)

This mnemonic feature of Label is really the only reason to keep this ancient conrol around. If you just need to display a little text, TextBlock works fine and lets you format individual words as a bonus.