如何使用加速器在WPF中创建自定义MenuHeader?
我想在WPF中创建一些自定义MenuHeader,以便在菜单项中包含(例如)图标和文本。
通常使用MenuItems,如果用纯文本填充"标题"字段,则可以使用下划线添加加速器。例如,_File
但是,如果我想放入UserControl,我相信此功能会中断,我将如何执行以下操作?
<Menu> <MenuItem> <MenuItem.Header> <UserControl> <Image Source="..." /> <Label Text="_Open" /> </UserControl> </MenuItem.Header> </MenuItem> ...
解决方案
回答
问题是我们将图像放置在MenuHeader内容的内部,这意味着我们将丢失加速键。如果我们只是想在菜单标题中添加图像,请执行以下操作。
<MenuItem Header="_Open"> <MenuItem.Icon> <Image Source="images/Open.png"/> </MenuItem.Icon> </MenuItem>
如果要进一步自定义外观,请修改菜单的控件模板和样式。根据经验,设置菜单和菜单项的样式要比设置其他WPF控件的样式困难得多。
回答
@ a7an:啊,我之前没有注意到Icon属性。那是一个好的开始。
但是,我特别想在某些MenuItems中添加一个额外的"按钮",以便可以具有" Pin"功能(有关功能概念,请参阅Office 2007中最近加载的文档列表)。
由于还需要编写代码,因此我可能需要对控件进行子类化并为按钮添加代码吗? (不怕搞砸MenuItem模板,已经必须做一次,如果必须的话,我会再次做!))
回答
我认为Icon属性适合需求。
但是,要回答原始问题,可以在编写菜单项的内容时保留Accelerator功能。如果我们在MenuItem中嵌套了内容,则需要像下面的第一个一样显式定义AccessText属性。使用内联表单时,将自动进行处理。
<Menu> <MenuItem> <MenuItem.Header> <StackPanel Orientation="Horizontal"> <Image Source="Images/Open.ico" /> <AccessText>_Open..</AccessText> </StackPanel> </MenuItem.Header> </MenuItem> <MenuItem Header="_Close" /> </Menu>
回答
首先考虑一下,我们会认为Icon属性只能包含图像。但是它实际上可以包含任何东西!当我以编程方式尝试将Image属性直接设置为具有图像路径的字符串时,偶然发现了这一点。结果是它没有显示图像,而是路径的实际文本!然后,我发现必须首先创建一个Image元素并将其设置为Icon属性。这使我认为Image属性只是菜单左侧图标区域中的任何内容容器,而我是对的。我试图在那儿放一个按钮,它起作用了!
这将在菜单项的"图标"区域中显示一个带有文本" i"的按钮。当我们单击按钮时,将触发Button_Click事件(单击按钮时不会触发LanguageMenu_Click)。
<MenuItem Name="LanguageMenu" Header="_Language" Click="LanguageMenu_Click"> <MenuItem.Icon> <Button Click="Button_Click">i</Button> </MenuItem.Icon> </MenuItem>
这导致不必为图标制作图像,而是使用带有符号字体的文本来显示简单的"图标"。下面的示例使用Wingdings字体,其中包含一个软盘符号。字体中的这个符号被映射到字符" <",在XAML中具有特殊含义,因此我们必须使用编码版本" <"。这像梦一样运作!下面在菜单项上将软盘符号显示为图标:
<MenuItem Name="mnuFileSave" Header="Save" Command="ApplicationCommands.Save"> <MenuItem.Icon> <Label VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Wingdings"><</Label> </MenuItem.Icon> </MenuItem>