【问题标题】:WPF shortcut in whole window整个窗口中的 WPF 快捷方式
【发布时间】:2016-07-27 08:33:26
【问题描述】:

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

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

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

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

是否有可能在整个应用程序中不进行大量修改就可以捕捉到关键压力?

一个。

【问题讨论】:

  • 您是否尝试将这些绑定放在 Shell 本身上?

标签: wpf keyboard-shortcuts


【解决方案1】:

听起来你的事件在它冒出那么远之前就已经被处理了。接下来我想知道您是否可以将输入绑定移动到您的窗口而不是用户控件。我的最终选择是删除您的输入绑定并创建一个全局签入代码。

由于您已经在使用输入绑定,因此我在下面添加了代码选项:

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

【讨论】:

    【解决方案2】:

    为其他人记录这个答案,因为有一种更简单的方法可以做到这一点,很少被引用,并且根本不需要接触 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.");
            }
        }
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-03
      • 1970-01-01
      • 2020-07-24
      • 2010-09-13
      • 2018-10-03
      • 2010-11-11
      相关资源
      最近更新 更多