Как сделать привязку кнопки- Enter на кнопку Button в WPF C#

264
17 мая 2018, 10:50

Хочу сделать так, чтобы при нажатии кнопки на клавиатуре, срабатывала кнопка из WPF. Вроде так можно было делать с помощью Label элемента управления.

Answer 1

Для клавиш Enter и Esc в WPF есть вспомогательные настройки у самой кнопки.

IsDefault = "true"
Установив данное значение в true - кнопка будет реагировать на нажатие клавиши Enter.

IsCancel = "true"
Установив данное значение в true - кнопка будет реагировать на нажатие клавиши Esc.

Однако!
В WPF принято использовать паттерн MVVM, а в нем не принято использовать Click события на кнопках или что то подобное, там принято использовать команды. Давайте попробуем реализовать пару команд с привязкой на заданные клавиши.

Для начала нам понадобится вспомогательный класс (я его возьму из этого урока).

public class RelayCommand : ICommand
{
    private Action<object> execute;
    private Func<object, bool> canExecute;
    public event EventHandler CanExecuteChanged
    {
        add => CommandManager.RequerySuggested += value;
        remove => CommandManager.RequerySuggested -= value;
    }
    public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
    {
        this.execute = execute;
        this.canExecute = canExecute;
    }
    public bool CanExecute(object parameter)
    {
        return canExecute == null || canExecute(parameter);
    }
    public void Execute(object parameter)
    {
        execute(parameter);
    }
}

Затем создадим ViewModel, в которой реализуем пару наших команд:

public class MainViewModel
{
    public MainViewModel()
    {
        HelloCommand = new RelayCommand(_ => Hello());
        GoodbyeCommand = new RelayCommand(_ => Goodbye());
    }
    public ICommand HelloCommand { get; }
    public ICommand GoodbyeCommand { get; }
    private void Hello()
    {
        Console.WriteLine("Привет мир!");
    }
    private void Goodbye()
    {
        Console.WriteLine("Мир, пока!");
    }
}

В окне, где наши кнопки зададим DataContext:

private MainViewModel MainViewModel { get; set; }
public MainWindow()
{
    InitializeComponent();
    MainViewModel = new MainViewModel();
    DataContext = MainViewModel;
}

Осталось чуть чуть поработать с XAML. Тут я лично буду задавать команды прямо окну с помощью InputBindings:

<Window.InputBindings>
    <KeyBinding Command="{Binding HelloCommand}" Key="F1"/>
    <KeyBinding Command="{Binding GoodbyeCommand}" Key="F2"/>
</Window.InputBindings>

Вот и все. Запускаем и видим, что при нажатие на F1 пишет в Debug окно "Привет мир!", а при нажатие на F2 увидим надпись "Мир, пока!".

Имея команду, мы ее смело можем прицепить и на кнопку:

<Button Command="{Binding HelloCommand}"/>
Answer 2

Кроме указанного в комментариях выше способа, можно сделать обработку события keydown на Вашем юзерконтроле. В бэккоде будет выглядеть как

KeyDown+=(sender,args) => { if (args.Key == Key.Enter) //вызов нужного метода

Так же можно воспользоваться keyBinding-ами. Их указывают в коллекции InputBindings окна или UserControl-а следующим образом:

<Window.InputBindings>
   <KeyBinding Key="S"
               Command="{Binding SaveAsCommand}"/>
   <KeyBinding Key="S"
               Modifiers="Control+Shift" 
               Command="{Binding SaveAsCommand}">
</Window.InputBindings>

Этот способ чаще всего применим при работе с MVVM, когда в DataContext-е окна или UserControl-а прописаны соответствующие команды с обработчиками.

READ ALSO
Как получить результат компиляции?

Как получить результат компиляции?

Делаю ide для языка C# на WinFormsПри запуске отправляю файлу csc

158
Переадресация при 404 asp mvc

Переадресация при 404 asp mvc

Как сделать, что бы при неверном url происходила переадресация на главную страницу ? Я пытаюсь реализовать это добавлением в webconfig :

209
Убрать рамку с groupbox c#

Убрать рамку с groupbox c#

Надо полностью убрать рамку с groupboxЧтоб остались только элементы внутри

483