【问题标题】:Implement Keyboard Shortcuts实现键盘快捷键
【发布时间】:2010-08-26 10:56:16
【问题描述】:

我目前使用onKeyDown 事件和if/else 语句来创建键盘快捷键:

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

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

} ...

但是,如果我有更多的键盘快捷键,这会变得很混乱。

有没有更好的实现方式?

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    你应该看看实现<CommandBindings><InputBindings>

    <Window.CommandBindings>
        <CommandBinding Command="Settings" CanExecute="SettingsCanExecute" Executed="SettingsExecuted" />
    </Window.CommandBindings>
    
    <Window.InputBindings>
        <KeyBinding Command="Settings" Key="S" Modifiers="Alt" />
    </Window.InputBindings>
    

    您的&lt;Button&gt; 则变为:

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

    SettingsCanExecute 方法确定何时启用按钮,并在按下按钮或按下组合键时调用SettingsExecuted 方法。

    然后您就不需要KeyDown 处理程序。

    在“开启密码”上有一个full tutorial

    有关CommandBindingsInputBindings 的更多信息,请访问 MSDN。

    【讨论】:

    • hmm...当我尝试&lt;CommandBinding Command="Preview" CanExecute ... 时,Command="Preview" 出现错误,提示无法转换“预览”。我正在使用 RibbonWindow 而不是 Window。这有什么不同吗?因为 RibbonWindow 扩展了 Window?
    • 我不确定我是否错过了教程中的任何内容。但是查看John Smith On WPF: Understanding Routed Commands 的演示代码,我想我需要在一个类上创建一个属性,然后在代码中引用它...Snipplr Code Snipplet
    【解决方案2】:

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

    【讨论】:

    • WPF 背后的核心思想之一是避免接触背后的代码。理想的 WPF/MVVM 程序背后有接近 0 行代码。虽然它工作得很好,但这不是一个好的做法。
    • 有趣。你有这方面的参考吗?我以前从未在印刷版中看到过,但如果这是真的,那就太好了。谢谢!
    • 我所知道的每个 MVVM 学习示例都会创建一个视图模型。在 XAML 中实例化该视图模型。并尽可能将 Code behind 保持为准系统。根据定义,您必须在代码中编写的所有内容都绑定到该特定视图。视图的任意性是 MVVM 中的一个基本概念。我的数学老师也常说“数学家是懒惰的作家——他们写的越多,他们就越容易犯错误”。我将其完全应用于编程。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多