Как выбрать элементы меню файла с помощью клавиатуры в WPF и C #?

Я разрабатываю приложение WPF UI.

У меня есть меню в верхней части экрана, в котором есть пункты меню «Файл» и «Справка».

В файле -> Backend features (сочетание клавиш ctrl + B), пункты подменю Exit (Ctrl + x).

при нажатии на любой элемент подменю открывается соответствующее окно.

Итак, без использования мыши, нажав ctrl + B или Ctrl + x, как можно открыть окно?

Кроме того, как я могу отобразить небольшую строку под буквой «F» в файле, чтобы при нажатии пользователем Alt + F меню «Файл» было видно.

Я работаю над WPF с использованием C #.


person user301016    schedule 10.09.2009    source источник


Ответы (3)


Вы захотите изучить ICommand, RoutedUICommand, InputGestureCollection и CommandManager. Это немного больше предварительной инфраструктуры, но шаблон команд WPF позволяет вам делиться командой через главное меню, контекстные меню, нажатия кнопок и т. Д. Если ваши действия записаны как команды, все места в вашем приложении, которые используют эту команду, будут разрешены / disable последовательно и добавляет еще один уровень косвенности, чтобы уменьшить повторение кода.

Следующий пример находится на VB.Net (извините, но, надеюсь, его будет легко перевести).

Реализуйте каждое из ваших необходимых действий как класс, реализующий ICommand:

Public Class OpenWindowCommand
  Implements ICommand

  Public Function CanExecute(parameter as Object) As Boolean Implements System.Windows.Input.ICommand.CanExecute
    'enter code that determines whether this command should be enabled or not
    'if you are listening to some backend logic that changes this state, you can
    'raise a CanExecuteChanged event
  End Function

  Public Sub Execute(parameter as Object) Implements System.Windows.Input.ICommand.Execute
     'code that you want to run for the action
  End Sub
 End Class

Создайте класс, в котором хранятся общие экземпляры каждой из ваших команд.

Public Class MyCommands
  Private Shared ReadyOnly openWindowCmd As ICommand = New OpenWindowCommand()
  Private Shared _openWindow as RoutedUICommand

  Shared Sub New()
    'static constructor
    Dim shortcut = New KeyGesture(Key.W, ModifierKeys.Control)
    RegisterCommand(_openWindow, "OpenWindow", "Open...", shortcut, AddressOf ExecuteOpenWindow, AddressOf CanExecuteOpenWindow)
    'add more commands as needed
  End Sub

  Private Shared Sub RegisterCommand(ByRef command as RoutedUICommand, ByVal name as String, ByVal text as String, ByVal gesture as KeyGesture, ByVal executeHandler as ExecutedRoutedEventHandler, ByVal canExecuteHandler as CanExecuteRoutedEventHandler)
    Dim inputs = New InputGestureCollection()
    If gesture IsNot Nothing Then inputs.Add(gesture)
    command = New RoutedUICommand(text, name, GetType(MyCommands), inputs)
    Dim binding = New CommandBinding(command, executeHandler, canExecuteHandler)
    Application.Current.MainWindow.CommandBindings.Add(binding)
    CommandManager.RegisterClassCommandBinding(GetType(Window),binding)
  End Sub

  Public Shared ReadOnly Property OpenWindow() as RoutedUICommand
    Get
      Return _openWindow
    End Get
  End Property
  Public Shared Sub ExecuteOpenWindow(sender as Object, e as ExecutedRoutedEventArgs)
    openCmd.Execute(e.Parameter)
  End Sub
  Public Shared Sub CanExecuteSave(sender as Object, e as CanExecuteRoutedEventArgs)
    e.CanExecute = openCmd.CanExecute(e.Parameter)
    e.Handled = True
  End Sub

End Class

Теперь в вашем XAML для вашего меню вы можете привязаться к этой команде:

<Window.Resources>
  <local:MyCommands x:Key="commands"/>
</Window.Resources>
...
<MenuItem Name="mnuOpenWindow" Command="{Binding Path=OpenWindow}"/>

Это немного больше, чем минимальное требование для использования команд, но в достаточно большом приложении я нашел эту дополнительную инфраструктуру весьма полезной. После того, как команды написаны и зарегистрированы, привязка к ним в любом документе XAML становится тривиальной, и, открывая общие свойства для каждого действия через класс MyCommands, вы можете получить доступ к командам только в коде, если это необходимо.

person gbc    schedule 10.09.2009

Чтобы добавить небольшую строку, представляющую ускоритель элемента меню, используйте подчеркивание в XAML:

<MenuItem Header="_File">
    <MenuItem Header="_Backend Features" />
    <MenuItem Header="E_xit" />
</MenuItem>

Что касается сочетаний клавиш, во-первых, я бы рекомендовал не использовать Ctrl + X для выхода, поскольку это обычно используется для Cut. Обычно для выхода нет сочетания клавиш, но нажатие Alt + F4 для закрытия главного окна будет иметь такой же эффект.

Что касается вашего фактического вопроса, у вас есть несколько вариантов, но для обоих вам нужно использовать команды для реализации обработки ваших MenuItems, а не события Click.

Первый вариант - установить InputBinding для каждой комбинации клавиш. В главном окне это будет сделано примерно так:

Для атрибута Command вам нужно будет указать выражение, представляющее команду для этого ярлыка (вы также должны использовать тот же Command при определении MenuItem). Если у вас есть класс Commands, вы можете сделать что-то вроде следующего:

static class Commands
{
    public static ICommand BackendFeaturesCommand = ...;
}

А затем в XAML:

<KeyBinding Key="B" Modifiers="Control"
    Command="{x:Static Commands.BackendFeaturesCommand}" />

Другой вариант - определить вашу команду как RoutedUICommand < / a> и укажите для него InputGesture. Это позаботится о подключении сочетания клавиш.

person Andy    schedule 10.09.2009
comment
Спасибо, Энди .. Я попробую то, что ты предложил. На самом деле у меня нет класса команд в моих проектах, поэтому могу ли я создать новый файл в проекте и добавить туда все команды? public static ICommand BackendFeaturesCommand, public static ICommand Exit ... Правильно ли я? ›› Спасибо Ramm - person user301016; 10.09.2009
comment
Да это верно. Если вы ищете ICommand в MSDN, я думаю, что там могут быть образцы того, как это настроить. - person Andy; 10.09.2009

Вы можете взглянуть на образец ShortCutKey из WPF Application Framework (WAF) . Это довольно просто понять.

person jbe    schedule 05.10.2009