我需要一种简单的方法来设置菜单项的快捷方式。
但这不适用于快捷方式,只需点击:
<MenuItem Header="Editar">
<MenuItem Header="Procurar" Name="MenuProcurar"
InputGestureText="Ctrl+F"
Click="MenuProcurar_Click">
<MenuItem.ToolTip>
<ToolTip>
Procurar
</ToolTip>
</MenuItem.ToolTip>
</MenuItem>
</MenuItem>
我正在使用WPF 4.0
答案 0 :(得分:57)
H.B。是的......我只是想增加更多精确度。
删除Click
上的MenuItem
个活动,并将其与Command
关联。
1 - 添加/创建命令:
<Window.CommandBindings>
<CommandBinding Command="Open" Executed="OpenCommandBinding_Executed"/>
<CommandBinding Command="SaveAs" Executed="SaveAsCommandBinding_Executed"/>
</Window.CommandBindings>
命令参考以下代码:
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
}
2 - 将命令与所需的键相关联:
<Window.InputBindings>
<KeyBinding Key="O" Modifiers="Control" Command="Open"/>
<KeyBinding Key="S" Modifiers="Control" Command="SaveAs"/>
</Window.InputBindings>
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>
这样,多个输入可以与同一命令相关联。
答案 1 :(得分:56)
您需要使用KeyBindings
(和CommandBindings
如果您(重新)使用RoutedCommands
,例如在ApplicationCommands
class中找到的那些),那么在快捷键的控件中应该工作。
e.g。
<Window.CommandBindings>
<CommandBinding Command="New" Executed="CommandBinding_Executed" />
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Key="N" Modifiers="Control" Command="New"/>
</Window.InputBindings>
对于自定义RoutedCommands
:
static class CustomCommands
{
public static RoutedCommand DoStuff = new RoutedCommand();
}
用法:
<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>
(实现ICommand
interface而不是使用RoutedCommands
通常更方便。您可以拥有一个构造函数,它可以使Execute
和CanExecute
的代理轻松创建命令做不同的事情,这种实现通常被称为DelegateCommand
或RelayCommand
。这样你就不需要CommandBindings
。)
答案 2 :(得分:10)
在我的拙见中,仅仅在标题处使用_就容易得多。这将自动创建所需的HotKey。
例如:
<MenuItem Header="_Editar">
<MenuItem Header="_Procurar" Name="MenuProcurar"
InputGestureText="Ctrl+F"
Click="MenuProcurar_Click">
<MenuItem.ToolTip>
<ToolTip>
Procurar
</ToolTip>
</MenuItem.ToolTip>
</MenuItem>
</MenuItem>
答案 3 :(得分:7)
您也可以在XAML中声明RoutedUICommand
:
<Window.Resources>
<RoutedUICommand x:Key="BuildCmd" Text="Build">
<RoutedUICommand.InputGestures>
<KeyGesture>CTRL+SHIFT+B</KeyGesture>
</RoutedUICommand.InputGestures>
</RoutedUICommand>
</Window.Resources>
进行绑定
<Window.CommandBindings>
<CommandBinding Command="{StaticResource BuildCmd}" Executed="BuildCmdExecuted"/>
</Window.CommandBindings>
并在MenuItem
<MenuItem Command="{StaticResource BuildCmd}"/>
讨论了另一种解决方案here。
答案 4 :(得分:7)
我过度偏向Windows.Forms&amp; gulp VB 6,所以我有点agree with Jonathan和Jase,这是一种更简单/程序化的方法来静态连接不是&#的事件处理程序39; t必然CommandBindings
。而且,我认为有。
我相信,this MSDN blog post可以在from here中找到使用非CommandBinding
处理程序,但强调按钮的好教程。我将提炼并定位MenuItem
s ...
首先,创建一个实现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;
}
正如本教程所指出的那样,你可以从任何地方调用这个命令,代码如......
var hwc = new HelloWorldCommand();
if (hwc.CanExecute(this))
hwc.Execute(this);
所以,让我们添加一种&#34;声明&#34;对于HelloWorldCommand
我们的窗口,以便我们以后可以使用它。在Window
标记内,将命令注册为资源:
<Window.Resources>
<local:HelloWorldCommand x:Key="hwc"/>
</Window.Resources>
现在我们有了一个简洁的快捷方式来链接到这个&#34;本地命名空间&#34;命令,"hwc"
,虽然你显然可以使用你想要的任何字符串。我们会在我们的xaml中使用它。
让我们将MenuItem
添加到我们的xaml中。我已经用[{1}}替换了股票Grid
,因为这是(对我来说)最简单的方式(等我),等间距的小部件填充了DockPanel
,尽管I&I #39;已将我剩下的所有UI留下了。
请注意每个Window
声明中都附带了Command="{StaticResource hwc}"
。关键是 MenuItem
- 请记住,这是我们在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>
- 请记住我们的CommandParameter
方法签名:Execute
。 Execute(object parameter)
参数是我们可以用来知道如何处理事件的参数。尝试运行此操作并注意CommandParameter
将使用MessageBox
中的任何内容来告知您事件的来源。我们手动完成所有操作,但这并不算太糟糕。
另请注意,您可以使这些对象像您一样复杂。您可以使用CommandParameter
标记中的属性来定义参数,也可以使用&#34; real&#34; MenuItem
标记,如上面的“打开”菜单项,用于定义复杂的内容。在这种情况下, 我们正在传递整个父<MenuItem.CommandParameter>
对象 ,这是抛出我们VB6的最简单(但不是最干净)方式ish context进入事件处理程序代码。
Window
添加键盘快捷键(又名&#34;回答OP&#34;)现在我们终于可以回答原来的问题!让我们最后连接MenuItem
菜单项的键盘快捷键。您注意到我们已经宣布了Close
。就其本身而言, InputGestureText
只是化妆品。如果我们过于挑剔,我们可以说创建键盘快捷键的机制与InputGestureText
根本没有任何直接的内在联系!
我们需要代替(或另外)在MenuItem
级别注册Ctrl-G的监听器以捕获击键。因此,在Window标签的顶层,插入此内容(基本上采用what's bragged about here):
Window
请注意,您可以将<Window.InputBindings>
<KeyBinding Modifiers="Control"
Key="G"
Command="{StaticResource hwc}"
CommandParameter="window input binding"
/>
</Window.InputBindings>
标记放在CommandParameter
中,方法是将其从自动关闭的XML移动到&#34;真实&#34;打开和关闭KeyBinding
标签。
我们已经完成了。运行您的应用程序,然后按Ctrl-G。 Whaddup。
非常直截了当,一旦你有了球员的直线,而且比我对大多数对命令和KeyBinding
的暗示要少得多的魔术束缚,我认为。
可能的专业提示:
整个
MenuItems
事情让我困惑了一段时间。对于特定的命令类型,这只是 ,我相信。也就是说,您无法连接任何您喜欢的CommandBinding
。像{{3}}这样的东西(事实上,这是一个不错的介绍教程!)......这可能不是很明显,但是通过使用命令,我们可以免费获得大量内容:项目上的键盘快捷键,文本和InputGestureText以及WPF根据活动控件及其自动启用/禁用项目州。在这种情况下,剪切和复制被禁用,因为没有选择文本,但启用了粘贴,因为我的剪贴板不是空的!
...有点神奇,并不一定好,当您对WPF菜单不熟悉时可能会让人感到困惑。
答案 5 :(得分:1)
这是 PowerShell 中的解决方案:
<Window x:Class="WpfApp1.Window1"
xmlns:local="clr-namespace:WpfApp1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="My App" Height="620" Width="950" >
<Window.InputBindings>
<KeyBinding Key="S" Modifiers="Ctrl"/>
</Window.InputBindings>
<Grid x:Name="MainGrid">
<!--Your GUI is here-->
<Menu Margin="0">
<MenuItem Header="_File">
<MenuItem x:Name="SaveProfile" Header="_Save Profile" InputGestureText="Ctrl+S"/>
</MenuItem>
</Menu>
</Grid>
</Window>
Add-Type @"
public class DelegateCommand : System.Windows.Input.ICommand
{
private System.Action<object> _action;
public DelegateCommand(System.Action<object> action)
{
_action = action;
}
public bool CanExecute(object parameter)
{
return true;
}
public event System.EventHandler CanExecuteChanged = delegate { };
public void Execute(object parameter)
{
_action(parameter);
}
}
"@
$hash.Window.InputBindings[0].Command = New-Object DelegateCommand( { Save-Profile } )
function Save-Profile {
Write-Host "Save Profile"
# Your logic goes here
}
感谢 Nicholas Wolverson 提供有关如何为命令创建类型的提示。
答案 6 :(得分:0)
这对我有用
<ContextMenu PreviewKeyUp="ContextMenu_PreviewKeyUp">
<MenuItem Header="Delete" Click="DeleteID" />
</ContextMenu>
后面的代码:
private void ContextMenu_PreviewKeyUp(object sender, KeyEventArgs e)
{
ContextMenu contextMenu = sender as ContextMenu;
if (e.Key == Key.D)
{
//DELETE ID
}
contextMenu.IsOpen = false;
}