自定义命令忽略热键

时间:2015-12-28 06:10:24

标签: 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 1", "Header1", typeof(EditCommands), gestures);

然后我在我的窗口的XAML中添加了CommandBindings部分。

<!-- local refers to my application's namespace -->
<Window.CommandBindings>
    <CommandBinding Command="local:EditCommands.Header1" Executed="CommandBinding_Executed" CanExecute="CommandBinding_CanExecute"></CommandBinding>
</Window.CommandBindings>

最后,在关联的Ribbon控件中添加了一个命令条目。

<RibbonButton Label="Header 1" Command="local:EditCommands.Header1" SmallImageSource="Images\small.png" ToolTipTitle="Header 1" ToolTipDescription="" ToolTipImageSource="Images\small.png"></RibbonButton>

单击功能区按钮可按预期执行处理程序。但是,按Ctrl+1似乎根本没有效果。如何识别我的热键?

5 个答案:

答案 0 :(得分:2)

其他一切必须继续。是否有一些元素在使用包含命令的命令绑定到达元素之前处理键输入?

找出类似事物的有用工具是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>

答案 1 :(得分:2)

您好我完全同意 Johan Jane ,您的代码适合我。但我只能在一种情况下重现那种奇怪的行为。如果您有多个具有相同手势的命令,则只会触发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>

 2.背后的代码:

    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);
    }
}

所以我可以建议你唯一的一件事;检查是否有其他命令(可能不是自定义)已经在使用您尝试定义的手势。

此致

答案 2 :(得分:1)

找到this example。也许您错过了KeyBindingInputBindings.Add部分。

KeyGesture keyg = new KeyGesture(Key.V, ModifierKeys.Control);  
KeyBinding kb = new KeyBinding(Window1.CtrlVCommand,keyg);  
InputBindings.Add(kb); 

您的代码看起来非常相似,但遗漏了您所显示的内容。

我在搜索wpf ribbon button shortcut key之后发现了大约5个链接。

为了使上述示例按照您想要的方式使用Ctrl + 1,我更新了这一行,如下所示:

KeyGesture keyg = new KeyGesture(Key.D1, ModifierKeys.Control);

如果这不起作用,也许您可​​以采取上述工作样本,开始将项目中的部分添加到其中,并查看它何时/何​​地中断。如果您可以发布一个显示此问题的完整,最小的解决方案,也许我/我们可以调试。

更多信息:

在进行更多研究时,我遇到了reference on input bindings#1084 A KeyBinding Binds a Command to a Key

  

用户界面元素有一个CommandBindings集合,其中包含命令绑定对象,指示元素支持哪些命令以及命令绑定的代码。

     

用户界面元素还有一个包含KeyBinding和MouseBinding实例的InputBindings集合,每个实例都将键盘或鼠标输入映射到CommandBindings集合中也存在的命令。

最后,InputBinding

上有MSDN

答案 3 :(得分:1)

下面的代码对我有用,如果我点击“标题1”功能区项目或使用Ctrl + 1,“执行”将打印到控制台输出。因此,我必须同意约翰的观点,即在您的应用程序主窗口中必须有其他内容,而不是您向我们展示的内容。

命令

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>
    <CommandBinding Command="local:EditCommands.Header1" Executed="CommandBinding_OnExecuted" CanExecute="CommandBinding_OnCanExecute"></CommandBinding>
</Window.CommandBindings>

<Grid>
    <Ribbon>
        <RibbonButton Label="Header 1" Command="local:EditCommands.Header1" ToolTipTitle="Header 1" ToolTipDescription=""/>
    </Ribbon>
</Grid>

背后的代码

private void CommandBinding_OnExecuted(object sender, ExecutedRoutedEventArgs e)
{
    Console.WriteLine("Executed");
}

private void CommandBinding_OnCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = true;
}

答案 4 :(得分:0)

您尝试在此处实现的内容可通过直接输入到Windows或您想要的容器控件来解决!

<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>