Реализация сочетаний клавиш - PullRequest
6 голосов
/ 26 августа 2010

В настоящее время я использую событие onKeyDown и оператор if/else для создания сочетаний клавиш:

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

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

} ...

Однако, если у меня есть еще несколько сочетаний клавиш, это становится грязным.

Есть ли лучшая реализация?

Ответы [ 2 ]

17 голосов
/ 26 августа 2010

Вам следует взглянуть на реализацию <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.

Полное руководство по включению кода *.

Более подробную информацию о CommandBindings и InputBindings можно найтина MSDN.

2 голосов
/ 27 июля 2016

Документирование этого ответа для других, поскольку есть гораздо более простой способ сделать это, на который редко ссылаются, и вообще не требующий касания XAML.

Чтобы связать сочетание клавиш, в конструкторе Window просто добавьте новую привязку клавиш в коллекцию InputBindings. В качестве команды передайте свой произвольный класс команд, который реализует ICommand. Для метода execute просто реализуйте любую необходимую логику. В моем примере ниже мой класс 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.");
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...