Сочетания клавиш в WPF - PullRequest
       24

Сочетания клавиш в WPF

119 голосов
/ 01 сентября 2009

Я знаю об использовании _ вместо &, но я смотрю на все сочетания клавиш типа Ctrl +.

Ctrl + Z для отмены, Ctrl + S для сохранения и т. Д.

Существует ли «стандартный» способ их реализации в приложениях WPF? Или это случай, когда вы свернетесь сами и подключите их к какой-либо команде / контролю?

Ответы [ 8 ]

159 голосов
/ 25 сентября 2009

Я понимаю, что стандартным способом является создание команд, а затем добавление к ним ваших сочетаний клавиш в качестве InputGestures.

Это позволяет сочетаниям клавиш работать, даже если они не подключены к каким-либо элементам управления. А поскольку пункты меню понимают жесты клавиатуры, они автоматически отобразят вашу комбинацию клавиш в тексте пунктов меню, если вы подключите эту команду к своему элементу меню.

  1. Создание статического атрибута для хранения команды (предпочтительно как свойство в статическом классе, который вы создаете для команд - но для простого примера, просто используя статический атрибут в window.cs):

    public static RoutedCommand MyCommand = new RoutedCommand();
    
  2. Добавьте сочетание клавиш, которое должно вызывать метод:

    MyCommand.InputGestures.Add(new KeyGesture(Key.S, ModifierKeys.Control));
    
  3. Создайте привязку команды, которая указывает на ваш метод для вызова при выполнении. Поместите их в привязки команд для элемента пользовательского интерфейса, под которым он должен работать (например, окна), и метода:

    <Window.CommandBindings>
        <CommandBinding Command="{x:Static local:MyWindow.MyCommand}" Executed="MyCommandExecuted"/>
    </Window.CommandBindings>
    
    private void MyCommandExecuted(object sender, ExecutedRoutedEventArgs e) { ... }
    
87 голосов
/ 20 мая 2011

Я обнаружил, что это именно то, что я искал в связи с привязкой ключей в WPF:

<Window.InputBindings>
        <KeyBinding Modifiers="Control"
                    Key="N"
                    Command="{Binding CreateCustomerCommand}" />
</Window.InputBindings>

См. Сообщение в блоге MVVM CommandReference и привязка клавиш

12 голосов
/ 31 октября 2015

Попробуйте этот код ...

Сначала создайте объект RoutedComand

  RoutedCommand newCmd = new RoutedCommand();
  newCmd.InputGestures.Add(new KeyGesture(Key.N, ModifierKeys.Control));
  CommandBindings.Add(new CommandBinding(newCmd, btnNew_Click));
9 голосов
/ 01 сентября 2009

Это зависит от того, где вы хотите их использовать.

Элементы управления

TextBoxBase уже реализуют эти сочетания клавиш. Если вы хотите использовать пользовательские сочетания клавиш, обратите внимание на команды и жесты ввода. Вот небольшой учебник из Включите код : Учебник WPF - Связывание команд и пользовательские команды

4 голосов
/ 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)
        {
            ExecuteDelegate();
        }
        else
        {
            throw new InvalidOperationException();
        }
    }
}
3 голосов
/ 03 декабря 2017

У меня была похожая проблема, и я нашел ответ @ aliwa самым полезным и элегантным решением; однако мне нужна была конкретная комбинация клавиш, Ctrl + 1 . К сожалению, я получил следующую ошибку:

«1» не может использоваться в качестве значения «Ключ». Числа не являются допустимыми значениями перечисления.

Немного продолжив поиск, я изменил ответ @ aliwa следующим образом:

<Window.InputBindings>
    <KeyBinding Gesture="Ctrl+1" Command="{Binding MyCommand}"/>
</Window.InputBindings>

Я обнаружил, что это прекрасно работает для любой комбинации, в которой я нуждался.

2 голосов
/ 23 апреля 2013

VB.NET:

Public Shared SaveCommand_AltS As New RoutedCommand

Внутри события загружено :

SaveCommand_AltS.InputGestures.Add(New KeyGesture(Key.S, ModifierKeys.Control))

Me.CommandBindings.Add(New CommandBinding(SaveCommand_AltS, AddressOf Me.save))

XAML не требуется.

0 голосов
/ 05 февраля 2014

Как связать команду с MenuItem:

<MenuItem Header="My command" Command="{x:Static local:MyWindow.MyCommand}"/>
...