我正在开发一个WPF UI应用程序。

我在屏幕顶部有一个菜单,其中包含文件,帮助菜单项。

在档案中 - >后端功能(快捷键是ctrl + B),退出(Ctrl + x)子菜单项。

单击任何子菜单项时,将打开相应的窗口。

所以,不用鼠标,按ctrl + B或Ctrl + x,如何打开窗口?

另外,如何在“F”下面显示一条小线。在文件中,以便当用户按下Alt + F时,文件菜单应该是可见的。

我正在使用C#开发WPF。

有帮助吗?

解决方案

您需要调查ICommand,RoutedUICommand,InputGestureCollection和CommandManager。它有一些前期基础架构工作,但WPF命令模式允许您在主菜单,上下文菜单,按钮单击等共享命令。将您的操作写为命令,应用程序中使用命令的所有位置将启用/一致地禁用它并添加一个间接层以减少代码重复。

以下示例在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类为每个操作公开共享属性,如果需要,您可以纯粹在代码中访问这些命令。

其他提示

要添加代表菜单项加速器的小行,请在XAML中使用下划线:

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

对于快捷键,首先我建议不要使用 Ctrl + X 进行退出,因为它通常用于剪切。通常退出没有快捷键,但按 Alt + F4 关闭主窗口将产生相同的影响。

关于您的实际问题,您有几个选项,但是对于两者都需要使用命令来实现处理您的MenuItem而不是 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 ,并为其指定 InputGesture 。这将为您安排快捷键的连接。

scroll top