2

我正在开发 MVVM 应用程序,我想为我的应用程序创建全局快捷方式。有必要在模块之间导航应用程序。我有带有代码的主窗口:

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

当我专注于我的窗户时,它会起作用,

但是当我将注意力集中在那个 UserControl 中的 TextBox 上时会出现问题(命令没有被触发)。

是否有可能在整个应用程序中不进行大量修改的情况下抓住关键压力?

一种。

4

2 回答 2

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");
    }
于 2013-07-15T19:45:16.270 回答
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.");
        }
    }
}

我确信这也可以用于其他控件,但还没有尝试过。

于 2016-07-27T00:33:26.017 回答