C# 忽略自定义命令的热键
我正在编写我的第一个WPF应用程序,并试图让我的自定义命令正常工作C# 忽略自定义命令的热键,c#,wpf,xaml,C#,Wpf,Xaml,我正在编写我的第一个WPF应用程序,并试图让我的自定义命令正常工作 public static RoutedUICommand Header1 { get; private set; } . . . gestures = new InputGestureCollection(); gestures.Add(new KeyGesture(Key.D1, ModifierKeys.Control, "Ctrl+1")); Header1 = new RoutedUICommand("Header
public static RoutedUICommand Header1 { get; private set; }
.
.
.
gestures = new InputGestureCollection();
gestures.Add(new KeyGesture(Key.D1, ModifierKeys.Control, "Ctrl+1"));
Header1 = new RoutedUICommand("Header 1", "Header1", typeof(EditCommands), gestures);
然后,我在窗口的XAML中添加了一个CommandBindings
部分
最后,将命令项添加到关联的功能区控件
单击功能区按钮将按预期执行处理程序。但是,按Ctrl+1似乎没有任何效果。如何识别我的热键?已找到。可能您缺少KeyBinding
和InputBindings。请添加部分
KeyGesture keyg = new KeyGesture(Key.V, ModifierKeys.Control);
KeyBinding kb = new KeyBinding(Window1.CtrlVCommand,keyg);
InputBindings.Add(kb);
您的代码看起来非常相似,但是您所显示的代码中缺少这些代码
在搜索wpf功能区按钮快捷键后,我找到了大约5个链接
为了使上述示例能够像您所希望的那样使用Ctrl+1,我更新了这一行,如下所示:
KeyGesture keyg = new KeyGesture(Key.D1, ModifierKeys.Control);
如果这不起作用,也许您可以使用上面的工作示例,开始将项目中的片段添加到其中,并查看其何时/何处中断。如果您可以发布一个完整的、最小的解决方案来展示这个问题,也许我/我们可以进行调试
更多信息:
在进一步的研究中,我发现了这个
用户界面元素具有CommandBindings集合,其中包含命令绑定对象,这些对象指示元素支持哪些命令以及命令绑定到的代码
用户界面元素还有一个InputBindings集合,其中包含KeyBinding和MouseBinding实例,每个实例都将键盘或鼠标输入映射到CommandBindings集合中也存在的命令
最后,还有MSDN在上,肯定还有别的事情发生。在键输入到达包含您的命令的命令绑定的元素之前,是否有某个元素处理该键输入
Snooop是一个很有用的工具,它可以用来解决类似的问题
使用下面的代码,只要按下Ctrl+1,就会调用HandleHeader1
public static class MyCommands
{
public static RoutedUICommand Header1 { get; } = new RoutedUICommand("Header 1", "Header1", typeof(MyCommands), new InputGestureCollection { new KeyGesture(Key.D1, ModifierKeys.Control, "Ctrl+1") });
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void HandleHeader1(object sender, ExecutedRoutedEventArgs e)
{
}
}
<Window x:Class="WpfApplication2.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:local="clr-namespace:WpfApplication2"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.CommandBindings>
<CommandBinding Command="local:MyCommands.Header1" Executed="HandleHeader1"/>
</Window.CommandBindings>
<StackPanel>
<TextBox/>
</StackPanel>
</Window>
公共静态类MyCommands
{
public static RoutedUICommand Header1{get;}=新的RoutedUICommand(“Header 1”、“Header1”、typeof(MyCommands)、新的InputGestureCollection{new keypostation(Key.D1,ModifierKeys.Control,“Ctrl+1”);
}
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
}
私有void HandleHeader 1(对象发送方,ExecutedRoutedEventArgs e)
{
}
}
您在这里尝试实现的内容可以通过直接输入绑定到您想要的窗口或容器控件来解决
<Window.InputBindings>
<KeyBinding Command="{x:Static local:EditCommands.Header1}" Gesture="CTRL+1" />
</Window.InputBindings>
我使用这种方法是为了将表示逻辑与业务逻辑分开(而且由于您已经绑定到命令,所以遵循MVVM模式可能是个好主意)。
除此之外,您还可以将相同的快捷方式绑定到不同的容器控件
强制用户控制焦点:
<Window FocusManager.FocusedElement="{Binding ElementName=ribbon}">
<RibbonButton x:Name="ribbon" Label="Header 1" Command="local:EditCommands.Header1" Focusable="True"/>
</Window>
下面的代码适用于我,如果我单击“标题1”功能区项或使用Ctrl+1,则“已执行”将打印到控制台中的输出。因此,我必须同意Johan的观点,即在应用程序主窗口中,除了您向我们显示的内容之外,还必须有其他内容
命令
public class EditCommands
{
public static RoutedUICommand Header1 { get; private set; }
static EditCommands()
{
var gestures = new InputGestureCollection();
gestures.Add(new KeyGesture(Key.D1, ModifierKeys.Control, "Ctrl+1"));
Header1 = new RoutedUICommand("Header 1", "Header1", typeof(EditCommands), gestures);
}
}
XAML
嗨,我完全同意约翰和简的观点,你的代码是为我工作的。但我只能在一种情况下重现这种奇怪的行为。如果有多个命令具有相同的手势,则只会触发Window.CommandBindings部分中定义的第一个命令。这是我的代码,你可以查一下。
1.Xaml:
<ribbon:RibbonWindow x:Class="SoRibbonWpfApplivationHelpAttempt.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ribbon="http://schemas.microsoft.com/winfx/2006/xaml/presentation/ribbon"
xmlns:soRibbonWpfApplivationHelpAttempt="clr-namespace:SoRibbonWpfApplivationHelpAttempt"
Title="MainWindow" Height="350" Width="525">
<Window.CommandBindings>
<CommandBinding Command="soRibbonWpfApplivationHelpAttempt:EditCommands.PandaButton" Executed="CommandBinding_Executed_P" CanExecute="CommandBinding_CanExecute_P"></CommandBinding>
<CommandBinding Command="soRibbonWpfApplivationHelpAttempt:EditCommands.Header1" Executed="CommandBinding_Executed" CanExecute="CommandBinding_CanExecute"></CommandBinding>
</Window.CommandBindings>
<Grid>
<ribbon:Ribbon x:Name="RibbonWin" SelectedIndex="0" IsEnabled="True">
<ribbon:Ribbon.HelpPaneContent>
<ribbon:RibbonButton SmallImageSource="Images/Penguins.jpg"
ToolTipTitle="Header 1" ToolTipDescription="" ToolTipImageSource="Images/Penguins.jpg"
Command="soRibbonWpfApplivationHelpAttempt:EditCommands.Header1"/>
</ribbon:Ribbon.HelpPaneContent>
<ribbon:Ribbon.QuickAccessToolBar>
<ribbon:RibbonQuickAccessToolBar>
<ribbon:RibbonButton x:Name ="Save" SmallImageSource="Images\Koala.jpg"
ToolTipTitle="Header 1" ToolTipDescription="" ToolTipImageSource="Images/Koala.jpg"
Command="soRibbonWpfApplivationHelpAttempt:EditCommands.PandaButton"/>
</ribbon:RibbonQuickAccessToolBar>
</ribbon:Ribbon.QuickAccessToolBar>
</ribbon:Ribbon>
<TextBox VerticalAlignment="Bottom" HorizontalAlignment="Stretch" BorderBrush="Red"/>
</Grid>
所以我只能建议你一件事;检查是否有其他一些命令(可能不是自定义命令)正在使用您尝试定义的手势
关于,@AnjumSKhan:NumLock不应该影响键.D1
键的行为(本例中有键.NumPad1
键)。@AnjumSKhan:我的热键似乎都没有被识别出来。@JonathanWood嗨,我检查了各种热键组合,包括urs,它在这里工作正常。请首先检查您的命令是否实际执行。另外,请尝试对您的命令使用正常的按钮
,并进行验证。@AnjumSKhan:如果我单击Ribbon按钮,该命令将被执行。但是我的命令都不是用热键执行的。我试着添加一个常规按钮--它现在只是被禁用了。我可以再玩一会儿。你是如何定义命令并将其绑定到你的窗口的?还有,你的窗口的CommandBinding\u CanExecute
方法是什么样子的?如果我必须在其他地方指定它们,我真的不明白在keyperstation
中指定键有什么意义。此外,除了没有指定击键描述外,您创建键手势的代码与我的代码看起来相同。这会有什么帮助?您是否尝试过我在尝试研究您的问题的答案并添加到其中以模拟您的项目时发现的示例代码?我将代码复制到我的机器上,如上图所示更改了1行,它就工作了。我看了其他一些代码,它们都是这样工作的,所以我从来没有质疑过。如果我写的没有帮助,也许其他人会提供一些东西。我一直在看。我不明白什么是InputBindings
。我现在明白你在说什么修改那条线了。我将继续研究该代码。显然,需要做更多的工作,因为这不会激活命令。更麻烦的是,我不明白为什么我需要在这么多不同的地方指定热键。回到过去,我们必须使用直观的拖放和双击来设计VB6应用程序。到目前为止,我一点也不喜欢WPF。除了InputBindins之外,没有必要指定任何其他内容。您的问题可能是密钥组合被另一个容器公司捕获
private void CommandBinding_OnExecuted(object sender, ExecutedRoutedEventArgs e)
{
Console.WriteLine("Executed");
}
private void CommandBinding_OnCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
<ribbon:RibbonWindow x:Class="SoRibbonWpfApplivationHelpAttempt.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ribbon="http://schemas.microsoft.com/winfx/2006/xaml/presentation/ribbon"
xmlns:soRibbonWpfApplivationHelpAttempt="clr-namespace:SoRibbonWpfApplivationHelpAttempt"
Title="MainWindow" Height="350" Width="525">
<Window.CommandBindings>
<CommandBinding Command="soRibbonWpfApplivationHelpAttempt:EditCommands.PandaButton" Executed="CommandBinding_Executed_P" CanExecute="CommandBinding_CanExecute_P"></CommandBinding>
<CommandBinding Command="soRibbonWpfApplivationHelpAttempt:EditCommands.Header1" Executed="CommandBinding_Executed" CanExecute="CommandBinding_CanExecute"></CommandBinding>
</Window.CommandBindings>
<Grid>
<ribbon:Ribbon x:Name="RibbonWin" SelectedIndex="0" IsEnabled="True">
<ribbon:Ribbon.HelpPaneContent>
<ribbon:RibbonButton SmallImageSource="Images/Penguins.jpg"
ToolTipTitle="Header 1" ToolTipDescription="" ToolTipImageSource="Images/Penguins.jpg"
Command="soRibbonWpfApplivationHelpAttempt:EditCommands.Header1"/>
</ribbon:Ribbon.HelpPaneContent>
<ribbon:Ribbon.QuickAccessToolBar>
<ribbon:RibbonQuickAccessToolBar>
<ribbon:RibbonButton x:Name ="Save" SmallImageSource="Images\Koala.jpg"
ToolTipTitle="Header 1" ToolTipDescription="" ToolTipImageSource="Images/Koala.jpg"
Command="soRibbonWpfApplivationHelpAttempt:EditCommands.PandaButton"/>
</ribbon:RibbonQuickAccessToolBar>
</ribbon:Ribbon.QuickAccessToolBar>
</ribbon:Ribbon>
<TextBox VerticalAlignment="Bottom" HorizontalAlignment="Stretch" BorderBrush="Red"/>
</Grid>
public partial class MainWindow : RibbonWindow
{
public MainWindow()
{
InitializeComponent();
}
private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
Debug.WriteLine("header 1");
}
private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void CommandBinding_CanExecute_P(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void CommandBinding_Executed_P(object sender, ExecutedRoutedEventArgs e)
{
Debug.WriteLine("panda");
}
}
public class EditCommands
{
public static RoutedUICommand Header1 { get; private set; }
public static RoutedUICommand PandaButton
{
get;
private set;
}
static EditCommands()
{
var gestures = new InputGestureCollection {new KeyGesture(Key.D1, ModifierKeys.Control, "Ctrl+1")};
Header1 = new RoutedUICommand("Header 1", "Header1", typeof(EditCommands), gestures);
var pandaG = new InputGestureCollection { new KeyGesture(Key.D2, ModifierKeys.Control, "Ctrl+2") };
PandaButton = new RoutedUICommand("Panda Button", "PandaButton", typeof(EditCommands), gestures);
}
}