Fel*_*oto 47 wpf keyboard-shortcuts
我需要一种简单的方法来设置菜单项的快捷方式.
但这不适用于快捷方式,只需点击:
<MenuItem Header="Editar">
<MenuItem Header="Procurar" Name="MenuProcurar"
InputGestureText="Ctrl+F"
Click="MenuProcurar_Click">
<MenuItem.ToolTip>
<ToolTip>
Procurar
</ToolTip>
</MenuItem.ToolTip>
</MenuItem>
</MenuItem>
Run Code Online (Sandbox Code Playgroud)
我正在使用WPF 4.0
H.B*_*.B. 59
您需要在快捷方式应该起作用的控件中使用KeyBindings(CommandBindings如果您(重新)使用,RoutedCommands例如在ApplicationCommands类中找到的那些).
例如
<Window.CommandBindings>
<CommandBinding Command="New" Executed="CommandBinding_Executed" />
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Key="N" Modifiers="Control" Command="New"/>
</Window.InputBindings>
Run Code Online (Sandbox Code Playgroud)
对于自定义RoutedCommands:
static class CustomCommands
{
public static RoutedCommand DoStuff = new RoutedCommand();
}
Run Code Online (Sandbox Code Playgroud)
用法:
<Window
...
xmlns:local="clr-namespace:MyNamespace">
<Window.CommandBindings>
<CommandBinding Command="local:CustomCommands.DoStuff" Executed="DoStuff_Executed" />
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Key="D" Modifiers="Control" Command="local:CustomCommands.DoStuff"/>
</Window.InputBindings>
...
</Window>
Run Code Online (Sandbox Code Playgroud)
(实现ICommand接口而不是使用它通常更方便RoutedCommands.你可以有一个构造函数,它接受代理Execute并CanExecute轻松创建执行不同操作的命令,这些实现通常被称为DelegateCommand或RelayCommand.这种方式你不需要CommandBindings.)
Gui*_*ish 58
HB是对的......我只是想增加更多精确度.
删除Click您的事件MenuItem并将其与相关联Command.
1 - 添加/创建命令:
<Window.CommandBindings>
<CommandBinding Command="Open" Executed="OpenCommandBinding_Executed"/>
<CommandBinding Command="SaveAs" Executed="SaveAsCommandBinding_Executed"/>
</Window.CommandBindings>
Run Code Online (Sandbox Code Playgroud)
这些命令引用了以下代码:
private void OpenCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
Open();//Implementation of open file
}
private void SaveAsCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
SaveAs();//Implementation of saveAs
}
Run Code Online (Sandbox Code Playgroud)
2 - 将命令与所需键关联:
<Window.InputBindings>
<KeyBinding Key="O" Modifiers="Control" Command="Open"/>
<KeyBinding Key="S" Modifiers="Control" Command="SaveAs"/>
</Window.InputBindings>
Run Code Online (Sandbox Code Playgroud)
3 - 最后用菜单项分配命令(InputGestureText只是一个装饰文本):
<Menu Name="menu1">
<MenuItem Header="_File">
<MenuItem Name="menuOpen" Header="_Open..." Command="Open" InputGestureText="Ctrl+O"/>
<MenuItem Name="menuSaveAs" Header="_Save as..." Command="SaveAs" InputGestureText="Ctrl+S"/>
</MenuItem>
</Menu>
Run Code Online (Sandbox Code Playgroud)
这样,多个输入可以与同一命令相关联.
Ign*_*cia 11
在我看来,在标题中使用_更容易.这将自动创建所需的HotKey.
例如:
<MenuItem Header="_Editar">
<MenuItem Header="_Procurar" Name="MenuProcurar"
InputGestureText="Ctrl+F"
Click="MenuProcurar_Click">
<MenuItem.ToolTip>
<ToolTip>
Procurar
</ToolTip>
</MenuItem.ToolTip>
</MenuItem>
</MenuItem>
Run Code Online (Sandbox Code Playgroud)
您也可以RoutedUICommand在XAML中声明:
<Window.Resources>
<RoutedUICommand x:Key="BuildCmd" Text="Build">
<RoutedUICommand.InputGestures>
<KeyGesture>CTRL+SHIFT+B</KeyGesture>
</RoutedUICommand.InputGestures>
</RoutedUICommand>
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)
做绑定
<Window.CommandBindings>
<CommandBinding Command="{StaticResource BuildCmd}" Executed="BuildCmdExecuted"/>
</Window.CommandBindings>
Run Code Online (Sandbox Code Playgroud)
并在 MenuItem
<MenuItem Command="{StaticResource BuildCmd}"/>
Run Code Online (Sandbox Code Playgroud)
这里讨论另一种解决方案.
我对Windows.Forms和gulp VB 6 过于偏见,所以我同意Jonathan和Jase的观点,即必须采用更简单/程序化的方法静态连接不一定的事件处理程序CommandBindings.我想,有.
我相信,CommandBinding在这篇MSDN博客文章中可以找到使用非处理程序,但强调按钮的好教程.我会提炼并瞄准MenuItems ...
首先,创建一个实现类ICommand.当然,如果需要,您可以将它放在任何位置,甚至可以放在MainWindow.xaml.cs文件中,以使您的演示代码非常简单.CanExecute当你想要稍后删除菜单项时,你可能会想要更复杂,但是现在,我们只会启用菜单项.
public class HelloWorldCommand : ICommand
{
public void Execute(object parameter)
{
MessageBox.Show(@"""Hello, world!"" from "
+ (parameter ?? "somewhere secret").ToString());
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
}
Run Code Online (Sandbox Code Playgroud)
正如本教程有用的指出,您可以从任何地方调用此命令,代码如...
var hwc = new HelloWorldCommand();
if (hwc.CanExecute(this))
hwc.Execute(this);
Run Code Online (Sandbox Code Playgroud)
所以让HelloWorldCommand我们为我们的Window 添加一种"声明",以便我们以后可以使用它.在Window标签内部,将命令注册为资源:
<Window.Resources>
<local:HelloWorldCommand x:Key="hwc"/>
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)
现在我们有一个简洁的快捷方式来链接到这个"本地命名空间"命令"hwc",虽然你显然可以使用你想要的任何字符串.我们将在xaml中使用它.
让我们将MenuItems 添加到我们的xaml中.我已经Grid用a 替换了股票,DockPanel因为这是最简单的方式(对我来说)有等间距的小部件填充Window,尽管我已经离开了我的所有其余UI.
请注意Command="{StaticResource hwc}"每个MenuItem声明中的s .关键是hwc在那里 - 请记住,这是我们HelloWorldCommand在Window关卡中设置的快捷方式.而且,当然,StaticResource只是为了查看它Window的资源.我们没有约束力; 我们只是使用我们的快捷方式.
<DockPanel LastChildFill="True">
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
<MenuItem
Header="_Open"
Command="{StaticResource hwc}"
>
<MenuItem.CommandParameter>
<!-- so you could make this object as complex as you wanted,
like, say, your entire Window. See magic incantation, below. -->
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType=Window}" />
</MenuItem.CommandParameter>
</MenuItem>
<MenuItem
Header="_Close"
Command="{StaticResource hwc}"
CommandParameter="Close"
InputGestureText="Ctrl+G" />
<MenuItem
Header="_Save"
Command="{StaticResource hwc}"
CommandParameter="Save" />
<Separator />
<MenuItem
Header="_Quit"
Command="{StaticResource hwc}"
CommandParameter="Quit" />
</MenuItem>
</DockPanel>
Run Code Online (Sandbox Code Playgroud)
请注意,我们对所有内容使用相同的命令!但是我们如何判断哪个小部件抛出事件?为此,你需要使用CommandParameter- 记住我们Execute方法的签名:Execute(object parameter).该CommandParameter参数是我们可以用来知道如何处理事件的参数.尝试运行此操作,并注意MessageBox将使用的任何内容CommandParameter让您知道事件的来源.我们手动完成所有操作,但这并不算太糟糕.
另请注意,您可以根据需要使这些对象变得复杂.您可以使用MenuItem标记中的属性来定义参数,也可以使用"真实" <MenuItem.CommandParameter>标记(如上面的"打开"菜单项)来定义复杂的内容.在这种情况下,我们传递整个父Window对象,这是将VB6-ish上下文抛出到事件处理程序代码中的最简单(尽管不是最干净)的方法.
MenuItems 添加键盘快捷键(又名"回答OP")现在我们终于可以回答原来的问题!让我们最后连接Close菜单项的键盘快捷键.你会注意到我们已经宣布了InputGestureText.就其本身而言,InputGestureText只是化妆品.如果我们过于挑剔,我们可以争辩说,创建键盘快捷键的机制与根本没有任何直接的,固有的关系MenuItem!
我们需要代替(或另外)在Window级别注册Ctrl-G的监听器以捕获击键.所以在Window标签的顶层,插入这个(基本上从这里开始):
<Window.InputBindings>
<KeyBinding Modifiers="Control"
Key="G"
Command="{StaticResource hwc}"
CommandParameter="window input binding"
/>
</Window.InputBindings>
Run Code Online (Sandbox Code Playgroud)
请注意,您可以通过将CommandParameter标记KeyBinding从自动关闭的XML移动到"真正的"打开和关闭KeyBinding标记来将标记放入您的标记中.
我们已经完成了.运行您的应用程序,然后按Ctrl-G.Whaddup.
非常直截了当,一旦你拥有了球员,并且比大多数前奏命令更少魔术绑定MenuItems,我想.
可能的专业提示:
整件事
CommandBinding困扰了我一段时间.这只是针对特定的命令类型,我相信.也就是说,你不能只是连接任何Command你喜欢的.像这里吹嘘的东西(在一些不错的介绍教程!)......它可能不是很明显,但通过使用命令,我们可以免费获得大量内容:项目上的键盘快捷键,文本和InputGestureText以及WPF根据活动控件及其状态自动启用/禁用项目.在这种情况下,剪切和复制被禁用,因为没有选择文本,但启用了粘贴,因为我的剪贴板不是空的!
...有点神奇,并不一定好,当你是WPF菜单的新手时,可能会让人感到困惑.