-
通用界面控件:

WPF菜单控件

在大部分Windows应用程序中,通常我们的菜单(Menu)会至于窗口顶部,但是在WPF中为了保证较高的灵活性,实际上你可以在窗体的任意位置放置菜单控件(Menu Control),菜单控件(Menu Control)的高度和宽度也可以任由你的设定。

WPF有一个很好的控件用于创建菜单选项----Menu。在Menu中添加子项非常简单,你只需要向Menu中添加MenuItem即可。 MenuItem 可以拥有一系列子项,就像你在许多Windows程序中看到的一样,它允许你创建分层式的菜单。 我们直接跳入正题,来看一下示例代码如何使用Menu:

<Window x:Class="WpfTutorialSamples.Common_interface_controls.MenuSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MenuSample" Height="200" Width="200">
    <DockPanel>
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_File">
                <MenuItem Header="_New" />
                <MenuItem Header="_Open" />
                <MenuItem Header="_Save" />
                <Separator />
                <MenuItem Header="_Exit" />
            </MenuItem>
        </Menu>
        <TextBox AcceptsReturn="True" />
    </DockPanel>
</Window>

在大部分Windows应用程序中,通常我们的菜单(Menu)会至于窗口顶部,但是在WPF中为了保证较高的灵活性,实际上你可以在窗体的任意位置放置菜单控件(Menu Control),菜单控件(Menu Control)的高度和宽度也可以任由你的设定。

我定义了一个顶级条目,其中该条目下面有4个子条目和一个分割线。利用Header属性设置各个条目的标签(Lable),你应该注意到在每一个标签的第一个字符前有一个下划线(_)。在WPF的Meun控件中,这样的命名规则意味着窗体将会接收到相应的快捷键用于激活Meun中的子条目。这将会以从顶层依次向下展开层次的子项目的方式工作,在该例程中,如果按下Alt键的同时,依次按下F键,然后按下N键,那么标签名为New的子条目将会被选中激活。

图标和复选框

菜单项的两个常见特征,图标用于更轻松地识别菜单项做什么,以及复选表示打开和关闭特定功能。 WPF MenuItem支持两者,并且它非常易于使用:

<Window x:Class="WpfTutorialSamples.Common_interface_controls.MenuIconCheckableSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MenuIconCheckableSample" Height="150" Width="300">
    <DockPanel>
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_File">
                <MenuItem Header="_Exit" />
            </MenuItem>
            <MenuItem Header="_Tools">
                <MenuItem Header="_Manage users">
                    <MenuItem.Icon>
                        <Image Source="/WpfTutorialSamples;component/Images/user.png" />
                    </MenuItem.Icon>
                </MenuItem>
                <MenuItem Header="_Show groups" IsCheckable="True" IsChecked="True" />
            </MenuItem>
        </Menu>
        <TextBox AcceptsReturn="True" />
    </DockPanel>
</Window>

在这个例子中,我创建了二个顶级项,其中一个我添加了两个项:一个定义了图标,使用带有标准Image控件的Icon属性,以及我们使用IsCheckable属性的一个 允许用户选中和取消选中该项目。 我甚至使用IsChecked属性默认选中它。 在后台代码中,您可以读这些属性,以了解是否复选了给定的菜单项。

处理单击

当用户单击菜单项时,您通常想要做些什么。 最简单的方法是向MenuItem添加一个click事件处理程序,就像这样:

<MenuItem Header="_New" Click="mnuNew_Click" />

在后台代码中,您需要实现mnuNew_Click方法,如下所示:

private void mnuNew_Click(object sender, RoutedEventArgs e)
{
	MessageBox.Show("New");
}

这对于非常简单的应用程序或者初步原型设计来说就足够了,但在WPF中使用命令方式来完成事件处理。

键盘快捷键和命令

您可以像上面一样轻松处理菜单项的Click事件,但更常见的方法是使用WPF命令。 关于使用和创建命令有很多理论,他们在网站上有自己的文章类别,但是现在,我可以告诉你,它们在WPF中使用时有一些优点,特别是与菜单或工具栏结合使用时。

首先,它们确保您可以在工具栏,菜单甚至上下文菜单上执行相同的操作,而无需在多个位置实现相同的代码。 它们还使键盘快捷键的处理变得更加容易,因为与WinForms不同,WPF不会自动监听键盘快捷键,如果你将它们分配到菜单项 - 您必须手动执行此操作。

但是,在使用命令时,WPF会自动响应键盘快捷键。 菜单项的文本(Header)也会自动设置(尽管您可以根据需要覆盖它),InputGestureText也是如此,它向用户显示可以使用哪个键盘快捷键来调用特定的菜单项。 让我们直接跳到菜单与WPF命令的组合示例:

<Window x:Class="WpfTutorialSamples.Common_interface_controls.MenuWithCommandsSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MenuWithCommandsSample" Height="200" Width="300">
    <Window.CommandBindings>
        <CommandBinding Command="New" CanExecute="NewCommand_CanExecute" Executed="NewCommand_Executed" />
    </Window.CommandBindings>
    <DockPanel>
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_File">
                <MenuItem Command="New" />
                <Separator />
                <MenuItem Header="_Exit" />
            </MenuItem>
            <MenuItem Header="_Edit">
                <MenuItem Command="Cut" />
                <MenuItem Command="Copy" />
                <MenuItem Command="Paste" />
            </MenuItem>
        </Menu>

        <TextBox AcceptsReturn="True" Name="txtEditor" />
    </DockPanel>
</Window>
using System;
using System.Windows;
using System.Windows.Input;

namespace WpfTutorialSamples.Common_interface_controls
{
	public partial class MenuWithCommandsSample : Window
	{
		public MenuWithCommandsSample()
		{
			InitializeComponent();
		}

		private void NewCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = true;
		}

		private void NewCommand_Executed(object sender, ExecutedRoutedEventArgs e)
		{
			txtEditor.Text = "";
		}
	}
}

它可能不是很明显,但通过使用命令,我们免费获得了大量的东西:键盘快捷键,文本和InputGestureText以及WPF根据活动控件及其状态自动启用/禁用项目。 在这个案例中,剪切和复制被禁用,因为没有选择文本,但启用了粘贴,因为我的剪贴板不是空的!

因为WPF知道如何结合某些控件来处理某些命令,在这种情况下剪切/复制/粘贴命令与文本输入控件相结合,我们甚至不必处理他们的执行事件 - 他们开箱即用! 我们必须处理New命令,因为当用户激活它时,WPF无法猜测我们想要它做什么。 这是通过Window的CommandBindings完成的,所有这些都在命令章节中有详细解释。

小结

使用WPF菜单控件快速简单,甚至可以轻松创建复杂的菜单层次结构,并且在将其与WPF命令结合使用时,您可以免费获得更多功能。