2010-08-26 166 views
6

我目前使用的onKeyDown事件和if/else語句來創建鍵盤快捷鍵:實現鍵盤快捷鍵

if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift && e.Key == Key.Tab) { 

} else if (e.Key == Key.Tab) { 

} ... 

但是,如果我有好幾個快捷鍵,這就會變得混亂。

有更好的實施嗎?

回答

17

你應該看看如何實現<CommandBindings><InputBindings>

<Window.CommandBindings> 
    <CommandBinding Command="Settings" CanExecute="SettingsCanExecute" Executed="SettingsExecuted" /> 
</Window.CommandBindings> 

<Window.InputBindings> 
    <KeyBinding Command="Settings" Key="S" Modifiers="Alt" /> 
</Window.InputBindings> 

<Button>就變成了:

<Button Height="50" Width="50" Margin="50,5,0,0" Command="Settings" /> 

SettingsCanExecute方法確定按鈕時啓用,並且SettingsExecuted方法被調用時,該按鈕被按下或按鍵組合被擊中。

然後您不需要KeyDown處理程序。

關於開啓代碼有full tutorial

關於CommandBindingsInputBindings的更多信息可以在MSDN上找到。

+0

嗯......當我試着' 2010-08-26 14:42:56

+0

我不確定我是否錯過了本教程中的任何內容。但看看從[約翰史密斯在WPF:瞭解路由命令]演示代碼(http://joshsmithonwpf.wordpress.com/2008/03/18/understanding-routed-commands/)我想我需要創建一個屬性上然後在代碼中引用它... [Snipplr代碼Snipplet](http://snipplr.com/view/39602/cwpf-routed-commands/) – 2010-08-27 04:40:22

1

爲他人記錄這個答案,因爲有一種很簡單的方法來做到這一點很少被引用,並且根本不需要觸摸XAML。

要鏈接鍵盤快捷鍵,只需在Window構造函數中添加一個新的KeyBinding到InputBindings集合。作爲命令,傳入實現ICommand的任意命令類。對於執行方法,只需實現你需要的任何邏輯。在我下面的例子中,我的WindowCommand類接受一個委託,它將在調用時執行。當我構造新的WindowCommand以使用我的綁定進行傳入時,我只需在我的初始化程序中指示我希望WindowCommand執行的方法。

您可以使用此模式來創建自己的快捷鍵盤快捷鍵。

public YourWindow() //inside any WPF Window constructor 
{ 
    ... 
    //add this one statement to bind a new keyboard command shortcut 
    InputBindings.Add(new KeyBinding(//add a new key-binding, and pass in your command object instance which contains the Execute method which WPF will execute 
     new WindowCommand(this) 
     { 
     ExecuteDelegate = TogglePause //REPLACE TogglePause with your method delegate 
     }, new KeyGesture(Key.P, ModifierKeys.Control))); 
    ... 
} 

創建一個簡單的WindowCommand類,該類需要執行委託來觸發設置的任何方法。

public class WindowCommand : ICommand 
{ 
    private MainWindow _window; 

    //Set this delegate when you initialize a new object. This is the method the command will execute. You can also change this delegate type if you need to. 
    public Action ExecuteDelegate { get; set; } 

    //You don't have to add a parameter that takes a constructor. I've just added one in case I need access to the window directly. 
    public WindowCommand(MainWindow window) 
    { 
     _window = window; 
    } 

    //always called before executing the command, mine just always returns true 
    public bool CanExecute(object parameter) 
    { 
     return true; //mine always returns true, yours can use a new CanExecute delegate, or add custom logic to this method instead. 
    } 

    public event EventHandler CanExecuteChanged; //i'm not using this, but it's required by the interface 

    //the important method that executes the actual command logic 
    public void Execute(object parameter) 
    { 
     if (ExecuteDelegate != null) //let's make sure the delegate was set 
     { 
      ExecuteDelegate(); 
     } 
     else 
     { 
      throw new InvalidOperationException("ExecuteDelegate has not been set. There is no method to execute for this command."); 
     } 
    } 
} 
+3

WPF背後的核心思想之一是避免必須觸摸後面的代碼。理想的WPF/MVVM程序背後有接近0行的代碼。 雖然它工作得很好,但這不是很好的做法。 – Christopher 2016-07-29 23:03:26

+0

有趣。你有參考嗎?我從來沒有在印刷前看到過,但如果這是真的,那將是很好的瞭解。謝謝! – 2016-08-04 16:30:57

+0

我知道MVVM的每個學習示例都會創建一個View Model。 在XAML中實例化該視圖模型。 並保持代碼作爲準人的可能性背後的背後。 您必須在後面的代碼中編寫的所有內容都按照定義綁定到特定的視圖。視圖的任意性是MVVM的一個基本概念。 另外我的數學老師曾經說過:「數學家是懶惰的作家 - 他們寫得越多,他們犯的錯誤越多」。我將其用於編程。 – Christopher 2016-08-08 19:12:21