我试图在我的MenuItem中添加一个shourcut:
<Menu x:Name="menu" VerticalAlignment="Top">
<Menu.InputBindings>
<KeyBinding Modifiers="Control" Key="N" Command="{Binding NewTerrainCommand}" CommandParameter="{Binding ElementName=Viewport3D, Path=Camera}" />
</Menu.InputBindings>
<MenuItem Header="_File">
<MenuItem Header="_New Terrain" Command="{Binding NewTerrainCommand}" CommandParameter="{Binding ElementName=Viewport3D, Path=Camera}" InputGestureText="Ctrl+N" />
</MenuItem>
<MenuItem Header="_Edit" />
<MenuItem Header="_Window" />
<MenuItem Header="_Help" />
</Menu>
我读到这可以通过定义键绑定来完成,但这只会给我带来更多问题:
仍然无法正常工作,我很确定我错过了什么。
谢谢。
答案 0 :(得分:1)
首先解释一下:
将一个命令(在本例中为RoutedCommand
,或者通常和ICommand
的实现)视为通过Visual树传播的各种信号。在可视树的每个元素处,WPF检查是否存在针对该命令注册的特定操作,并且如果找到一个,则执行该操作。
在您的示例中,需要声明三种不同的关联:
MenuItem
需要与Command CanExecute
,Executed
)MenuItem
需要与Ctrl+N
组合键关联。 完成(#1)非常简单 - 您只需将命令指定为MenuItem
中的绑定。
(#2)更有趣。正如我前面提到的,命令用于通过Visual树中继信号以进行操作。这意味着可视树的不同部分必须声明它们各自处理该命令的能力。该声明是通过CommandBinding
进行的。 CommandBinding
将一个命令与可视实体的上下文中的操作(CanExecute
,Executed
)相关联。
假设执行我们的Command的方法将存在于主Window
类(通常为MainWindow
)中,我们需要在{{CommandBinding
上指定MainWindow
1}}实例。 (更确切地说,MainWindow
将是声明它处理所述命令的能力的类型之一。可以想象其他类型声明对同一Command
的兴趣 - 我们的以下示例恰好只有一种表示对处理命令感兴趣的类型。
一旦宣布了这种关联(在MainWindow和相关命令之间),每当触发Command(例如,由MenuItem
)时,WPF就会知道调用已注册的CanExecute
和{ {1}} Executed
中的方法,因为存在相应的MainWindow
来声明CommandBinding
能够处理命令的事实。
(#3)也相对容易。 MainWindow
具有RoutedCommand
属性,可以添加InputGestures
。添加后,与此命令关联的KeyGesture
将自动推断MenuItem
。
以下示例(主要来自您自己的代码,经过修改)显示了这一切是如何连接在一起的:
<强> MainWindow.xaml:强>
KeyGesture
<强> MainWindow.xaml.cs:强>
<Window x:Class="CommandsSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:system_windows_input="clr-namespace:System.Windows.Input;assembly=PresentationCore"
xmlns:local="clr-namespace:CommandsSample"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<!-- The following DataContext declaration simply means that the current instance of MainWindow (i.e., 'this')
is the operative DataContext for all data bindings specified in the rest of this XAML -->
<Window.DataContext>
<Binding RelativeSource="{RelativeSource Self}"/>
</Window.DataContext>
<Window.Resources>
<!-- Declare a RoutedCommand with an associated KeyGesture -->
<RoutedCommand x:Key="NewFileCommand">
<RoutedCommand.InputGestures>
<system_windows_input:KeyGesture>
Ctrl+N
</system_windows_input:KeyGesture>
</RoutedCommand.InputGestures>
</RoutedCommand>
</Window.Resources>
<!-- The following CommandBinding associates NewFileCommand with actions defined in the code behind -->
<Window.CommandBindings>
<CommandBinding Command="{StaticResource NewFileCommand}" CanExecute="CouldCreateNewFile" Executed="CreatenewFile"/>
</Window.CommandBindings>
<!-- Main UI consisting of a Menu and a TextBox -->
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
<!-- The New MenuItem will automatically infer the KeyGesture Ctrl+N from NewFileCommand -->
<MenuItem Header="_New" Command="{StaticResource NewFileCommand}" />
<MenuItem Header="_Open"/>
<MenuItem Header="_Save"/>
<Separator/>
<MenuItem Header="_Exit"/>
</MenuItem>
</Menu>
<TextBox AcceptsReturn="True" Text="{Binding FileText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DockPanel>
</Window>