在大部分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命令结合使用时,您可以免费获得更多功能。