2015-12-28 86 views
6

我正在寫我的第一個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); 

我再補充一個CommandBindings節我窗口的XAML。

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

最後,向相關的功能區控件添加了一個命令條目。

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

單擊功能區按鈕可按預期執行處理程序。但是,按Ctrl+1似乎完全沒有效果。我如何識別我的熱鍵?

+0

Checked NumLock? – AnjumSKhan

+0

@AnjumSKhan:NumLock不應該影響'Key.D1'鍵行爲(在這種情況下有'Key.NumPad1'鍵)。 – Dennis

+0

@AnjumSKhan:我的熱鍵似乎都沒有被識別。 –

回答

1

Found this example。也許你錯過了KeyBindingInputBindings.Add部件。

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

您的代碼看起來非常相似,但從您所顯示的內容中遺漏了這些代碼。

我在搜索後發現這個關於5個鏈接下來了wpf ribbon button shortcut key

要使用Ctrl上述樣品的工作+ 1像你想,我更新了這一行,像這樣:

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

如果這不起作用,或許你可以把上面的工作樣本,開始添加從你的項目到它的碎片,看看它何時何地破碎。如果你可以發佈一個完整的,最小的解決方案,展示這個問題,也許我/我們可以調試。

的更多信息:

在研究此更多,我跨越這個reference on input bindings#1084 A KeyBinding Binds a Command to a Key

的用戶界面元件具有包含命令對象綁定指示都支持哪些命令一化CommandBindings集合來元素和命令綁定的代碼。

用戶界面元素也有一個InputBindings集合,其中包含KeyBinding和MouseBinding實例,每個實例都將鍵盤或鼠標輸入映射到CommandBindings集合中也存在的命令。

最後是在MSDN上InputBinding

+0

如果我必須在其他地方指定它們,我真的不知道在KeyGesture中指定鍵的意義。此外,除了不指定擊鍵描述外,創建「KeyGesture」的代碼看起來與我的一樣。這將如何幫助? –

+0

當您試圖研究您的問題的答案並添加到模擬您的項目時,您是否嘗試過我找到的示例代碼?我將代碼複製到我的機器上,如上所示更改了1行,並且它工作正常。我查看了其他一些代碼,他們都以這種方式工作,所以我從來沒有問過這個問題。如果我寫的東西沒有幫助,也許別人會提供一些東西。 –

+0

我一直在看。我不明白'InputBindings'是什麼。我現在看到你對修改該行的看法。我將繼續研究該代碼。 –

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

那麼如果這個工程,我不明白爲什麼我的不。我注意到,RoutedUICommand構造函數的第三個參數是typeof(MainWindow),而不是保存命令的類的類型(在你的代碼中它是'MyCommands')。我不知道該怎麼做,但似乎都不適合我。我沒有添加任何東西來處理任何命令。 –

+0

我在代碼中看到的唯一區別是我也引用了其他一些元素(在我的例子中是'RibbonButton')的命令。 –

+0

Type參數對我來說只是一個錯誤。但正如你已經注意到的,在這種情況下不應該有任何區別。 –

0

您試圖在這裏實現的東西可以通過直接InputBindings到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> 
+0

顯然,有更多的需要使這項工作,因爲這不會激活命令。更麻煩的是,我不明白爲什麼我需要在這麼多不同的地方指定熱鍵。早在過去,我們必須使用直觀的拖放和雙擊來設計我們的VB6應用程序。到目前爲止,我根本不喜歡WPF。 –

+0

除了InputBindins之外,沒有必要指定其他任何東西。您的問題可能是該組合鍵被另一個容器控件捕獲。嘗試先專注於色帶,然後使用快捷鍵!您可以通過強制將初始焦點強制到功能區或禁止專注於捕獲快捷方式的容器來解決此問題。 –

+0

如果你的快捷方式被文本框捕獲,那麼看看這篇關於如何禁用默認文本框快捷鍵的文章:http://stackoverflow.com/questions/12941707/keybinding-in-usercontrol-doesnt-work-when-textbox-has -焦點 –

1

下面的代碼爲我工作,如果我點擊「標題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> 
    <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; 
} 
2

您好我完全同意約翰,你的代碼是爲我工作。但我只能在一種情況下重現那種奇怪的行爲。如果您有多個具有相同手勢的命令,則只會觸發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); 
    } 
} 

因此,我可以建議你的只有一兩件事;檢查是否有其他命令(可能不是自定義的),它們已經在使用您嘗試定義的手勢。

Regards,