A Brief Look at Menus in WPF

Menus are one of the most important parts of any application. This article will explain why, and show you how to build two kinds of menus using Windows Presentation Foundation. Let's get started.

Contributed by
Rating: 4 stars4 stars4 stars4 stars4 stars / 6
September 22, 2008
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

An application needs to have functionality in order to be of any use. However, that functionality needs to be accessible to the user. If it isn't, then it means nothing. This requires that the application be organized well. That is, the user must be able to easily figure out how to perform a particular task, and common tasks need to be in very obvious places.

One of the most important tools in the effort to create an organized and accessible user interface is the menu. Many applications feature a menu at the very top of the window, allowing the user to perform various functions, but many individual controls also have their own menus, called context menus, that enable a user to get increased functionality out of that control.

In this article, we'll take a look at both regular menus and context menus in Windows Presentation Foundation.

The Menu and MenuItem classes

A menu in WPF is represented by the Menu class. Like any other control, an instance of Menu may be created either declaratively or programatically. Here's the basic XAML required to begin creating it declaratively:


<Menu>

</Menu>


Also like any other control, a Menu must be positioned in the application. Of course, the obvious place to put a menu would be at the top of the application. You can get it there using a variety of layout controls-whatever fits your application.

The Menu class contains a boolean property called IsMainMenu. This property determines whether or not the menu will respond to the Alt or F10 keys, as the main menu of an application would be expected to do. The default value for this property is true. If you only have one menu in your application, then you need not worry about this property, but if you have multiple menus, you'll want to set the IsMainMenu properties of the non-main menus accordingly:


<Menu IsMainMenu="False">

</Menu>


The most important pieces of a menu, though, are its submenus and its items, so that's where we'll need to focus. A Menu is actually an ItemsControl (it inherits from MenuBase, which inherits from ItemsControl), so its items are stored in Items and ItemsSource. A Menu's items take the form of instances of the MenuItem class. A MenuItem can actually be used for multiple purposes. The simplest form it can take is a regular menu item. Normally, the item is given a Header (the text on the item). Here, we create two menu items to start with, File and Edit:


<Menu>

 <MenuItem Header="File">

 

 </MenuItem>

 <MenuItem Header="Edit">

 

 </MenuItem>

</Menu>


You can roll your mouse over File and Edit, and they'll act like normal menu items. But, as you know, File and Edit normally don't behave like this. Rather, they are actually submenus with their own child items. This brings us to the other form of a MenuItem: given children, it acts as a submenu. Within it can be placed other MenuItem objects. Let's add a few items to File and Edit:


<Menu>

 <MenuItem Header="File">

 <MenuItem Header="New" />

 <MenuItem Header="Open" />

 <MenuItem Header="Save" />

 <MenuItem Header="Quit" />

 </MenuItem>

 <MenuItem Header="Edit">

 <MenuItem Header="Copy" />

 <MenuItem Header="Cut" />

 <MenuItem Header="Paste" />

 </MenuItem>

</Menu>


Now, the File and Edit items will act as submenus, with various items under them, and the menu will look more like a normal menu. Of course, another tool to help organize menu items is separators. Separators are very easy to add. We could add one between the Save and Quit items of the above sample menu:


<MenuItem Header="Save" />

<Separator />

<MenuItem Header="Quit" />

More on MenuItem

In some situations, more functionality is needed for menu items. In certain situations, some menu items may need to be disabled. For example, consider a context menu for a standard text box, containing Copy, Cut and Paste menu items. If no text is highlighted, then it doesn't make sense for the user to be able to copy or cut anything. So, it makes sense for those options to be disabled.

Whether or not a menu item is enabled is determined by the value of IsEnabled. You can set IsEnabled to false in order to disable a menu item. For example, below, the Copy and Cut menu items would be disabled:


<MenuItem Header="Copy" IsEnabled="False" />

<MenuItem Header="Cut" IsEnabled="False" />

<MenuItem Header="Paste" />


Another useful bit of functionality is a check box of sorts on a menu item. Some menu items can be made to turn a feature on or off. If the feature is on, a check mark will be placed to the left of the menu item's text. If the feature is off, then the check mark will not appear.

This functionality is easy to implement. It involves two properties: IsCheckable and IsChecked. The IsCheckable property determines whether or not the item can be checked, and the IsChecked property determines whether or not the item actually is checked. The default value for IsChecked is false, so creating a checkable menu item without setting IsChecked will result in an unchecked menu item.

Below, we create a menu item that can be checked:


<MenuItem Header="Syntax Highlighting" IsCheckable="True" />


And here, we create a menu item that is checked by default:


<MenuItem Header="Standard Mode" IsCheckable="True"

 IsChecked="True" />


In order to make menus more accessible, it's a good idea to provide access keys for menu items. This will not only make keyboard-loving users happy, but it will allow people with various disabilities to use your application. The presence of an access key is indicated by an underlined letter in an item's label. The item can be "clicked" by pressing Alt and the underlined letter.

Access keys are very easy to implement. The process is the same as with any other control. When specifying the MenuItem's Header, simply add an underscore before the desired access key character. For example, with a File menu, an access key might be set up like this:


<MenuItem Header="_File">

...

</MenuItem>


Pressing the Alt key will show the F as being underlined, and then pressing the F key will activate the File menu.

Handling Input

When a user clicks a menu item, something will need to be done in response. The Click event is raised when a menu item is clicked, so this is the obvious place to give the user a response. The Click attribute can be used to point to an appropriate event handler:


<MenuItem Header="Quit" Click="MenuItem_Click" />


The actual event handler would look something like this:


private void MenuItem_Click(object sender, RoutedEventArgs e)

{

 // Do something

}


But recall from earlier that it's possible to make a menu item checkable. If this is the case, then it's a good idea to respond when the user has checked the menu item and when the user has unchecked the menu item. When the user checks an item, a Checked event is raised, and when the user unchecks an item, an Unchecked event is raised:


<MenuItem Header="Syntax Highlighting" IsCheckable="True"

 Checked="MenuItem_Checked"

 Unchecked="MenuItem_Unchecked" />


private void MenuItem_Checked(object sender, RoutedEventArgs e)

{

 // The user has checked the item

}


private void MenuItem_Unchecked(object sender, RoutedEventArgs e)

{

 // The user has unchecked the item

}


Working with the above three events allows for a consistent response each time. However, sometimes, the effect of a menu item changes depending on what the user is actually doing. For example, consider the Edit menu. The use can copy, cut and paste text using this menu. However, this is only appropriate with text boxes, and the exact targets may vary. Furthermore, the user can copy, cut and paste in other ways as well, so the menu shouldn't be the only originator of these events.

This is where commands come into play. Commands allow for various sources to originate a single action, and for the target to handle the action in its own way. A user may generate a Paste command through the main menu or through a keyboard shortcut, but the same command is generated both times. The same command can have different effects, however, depending on the target. One text box may allow formatting in the pasted text, and another text box may strip all formatting away.

Linking menu options to commands is very easy. The Command property of a MenuItem simply needs to be set to the desired command (represented by an ICommand). For example, say we wanted to link Copy, Cut and Paste events to menu items. These are fairly common commands, and their functionality is already set up for us (it's of course possible to create your own commands, but this article can't possibly cover all of that; we'll stick to the relationship between commands and menus). We'd set it all up like this:


<MenuItem Header="Copy"

 Command="ApplicationCommands.Copy"/>

<MenuItem Header="Cut"

 Command="ApplicationCommands.Cut" />

<MenuItem Header="Paste"

 Command="ApplicationCommands.Paste" />


Not only does it link the menu item with the command, but it also disables the menu items where appropriate (such as when there's nothing to copy, cut or paste), and it displays the appropriate keyboard shortcuts beside each item. In fact, we can even remove the headers if we're fine with the standard ones-they will automatically be set:


<MenuItem Command="ApplicationCommands.Copy"/>

<MenuItem Command="ApplicationCommands.Cut" />

<MenuItem Command="ApplicationCommands.Paste" />

Context Menus

Next come context menus, which are menus specific to a particular control. Context menus are created using the ContextMenu class. In the application's XAML, however, context menus must be placed within the control to which they're linked, within a special object.ContextMenu section:


<TextBox>

 <TextBox.ContextMenu>

 <ContextMenu>

 

 </ContextMenu>

 </TextBox.ContextMenu>

</TextBox>


Once the ContextMenu is created, items can be added to it as in a standard menu:


<ContextMenu>

 <MenuItem Header="Item 1" />

 <MenuItem Header="Item 2" />

 <MenuItem Header="Submenu">

 <MenuItem Header="Item 3" />

 </MenuItem>

</ContextMenu>


As you can see, then, context menus aren't very different at all from regular menus. They're just connected to a particular control and don't apply to the window as a whole.

In this article, we've taken a look at menus in WPF. However, there is certainly a lot more to be learned about menus. This article, then, is only intended to be an introduction to menus, not a comprehensive resource. But you should now know enough to use menus effectively within your applications.

blog comments powered by Disqus
WINDOWS SCRIPTING ARTICLES

- More Windows Scripting Workarounds from Nilpo
- Overloading Methods and More in VBScript
- Improving MFC for Windows Vista
- Regular Expressions in VBScript
- Working with Dates in WMI
- Completing Calendars with VBScript Date Func...
- Building Calendars with VBScript Date Functi...
- Working With Dates and Times in VBScript
- Designing WCF DataContract Classes Using the...
- Understanding Dates and Times in VBScript
- Working With Arrays in VBScript
- Compressed Folders in WSH
- Using .NET Interops in VBScript
- Nilpo`s Scripting Secrets, Vol I
- Database operations using Silverlight 2.0 WC...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 8 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials