2013-07-15 46 views
2

我正在開發MVVM應用程序,我想爲我的應用程序創建全局快捷方式。有必要在模塊之間導航應用程序。我有主窗口代碼:在整個窗口中的WPF快捷鍵

<UserControl.InputBindings> 
    <KeyBinding Command="{Binding ChangeModuleComand}" 
        Key="M" 
        Modifiers="Control"/> 
</UserControl.InputBindings> 

它工作時,我有我的重點窗口上,

但是有一個問題,當我有專注於在用戶控件文本框(命令是不啓動)。

是否有可能在整個應用程序中沒有大量修改的情況下捕捉到關鍵壓力?

答:

+0

您是否嘗試將這些綁定放在殼本身上? –

回答

2

這聽起來像你的事件正在處理之前,它泡了這麼遠。接下來,我想知道是否可以將輸入綁定移動到您的窗口而不是用戶控件。我最後的選擇是刪除你的輸入綁定並創建一個全局簽入代碼。

既然你已經與輸入綁定的工作,我已經添加下面的代碼選項:

//In App.xaml.cs 
    protected override void OnStartup(StartupEventArgs e) 
    { 
     base.OnStartup(e); 
     EventManager.RegisterClassHandler(typeof(UIElement), UIElement.KeyDownEvent, new RoutedEventHandler(GlobalClick)); 
    } 

    private void GlobalClick(object sender, RoutedEventArgs e) 
    { 
     var args = (KeyEventArgs) e; 
     if (args.KeyboardDevice.IsKeyDown(Key.M) && 
      args.KeyboardDevice.IsKeyDown(Key.LeftCtrl) || args.KeyboardDevice.IsKeyDown(Key.RightCtrl)) 
      MessageBox.Show("Works"); 
    } 
0

文檔化這個答案給別人,因爲有一個更簡單的可以做到這一點很少被引用的方式,並且完全不需要接觸XAML。

要在Window級別鏈接一個鍵盤快捷鍵,只需在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."); 
     } 
    } 
} 

我敢肯定,這也可以用於其他控件,但還沒有嘗試過。