我有一个非常简单的应用程序,我在其中尝试将键盘快捷方式绑定(bind)到绑定(bind)到菜单项的 WPF 命令。该应用程序本身仅包含一个 Menu
和一个 WebBrowser
控件。
当我在 WebBrowser
中时,键盘快捷键不会路由到 WPF 菜单。例如,在 Web 浏览器中聚焦时键入“Ctrl+O”会显示 IE 打开的页面。此外,在此应用程序中,除非我聚焦菜单(通过键入 Alt),否则输入绑定(bind)不会触发。例如,我无法通过单击标题栏然后键入快捷方式来关注 WPF 窗口。完整代码复制如下:
MainWindow.xaml
<Window x:Class="TestInputBindingsOnMenu.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="600" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Menu IsMainMenu="True" x:Name="_mainMenu" Grid.Row="0" />
<WebBrowser Source="http://google.com" Grid.Row="1" />
</Grid>
</Window>
MainWindow.xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace TestInputBindingsOnMenu
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Initialize();
}
private void Initialize()
{
MenuItem fileMenu = new MenuItem();
MenuItem fileNew = new MenuItem();
MenuItem fileOpen = new MenuItem();
MenuItem fileExit = new MenuItem();
fileMenu.Header = "File";
fileNew.Header = "New";
fileOpen.Header = "Open";
fileExit.Header = "Exit";
fileMenu.Items.Add(fileNew);
fileMenu.Items.Add(fileOpen);
fileMenu.Items.Add(fileExit);
_mainMenu.Items.Add(fileMenu);
var fileNewCommand = CreateCommand("New");
var fileOpenCommand = CreateCommand("Open");
var fileExitCommand = CreateCommand("Exit");
_mainMenu.CommandBindings.Add(new CommandBinding(fileNewCommand, ExecuteNew));
_mainMenu.CommandBindings.Add(new CommandBinding(fileOpenCommand, ExecuteOpen));
_mainMenu.CommandBindings.Add(new CommandBinding(fileExitCommand, ExecuteExit));
fileNew.Command = fileNewCommand;
fileOpen.Command = fileOpenCommand;
fileExit.Command = fileExitCommand;
_mainMenu.InputBindings.Add(new InputBinding(fileNewCommand, new KeyGesture(Key.N, ModifierKeys.Control)));
_mainMenu.InputBindings.Add(new InputBinding(fileOpenCommand, new KeyGesture(Key.O, ModifierKeys.Control)));
_mainMenu.InputBindings.Add(new InputBinding(fileExitCommand, new KeyGesture(Key.F4, ModifierKeys.Alt)));
}
private void ExecuteNew(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("New!!");
}
private void ExecuteOpen(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Open!!");
}
private void ExecuteExit(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Exit!!");
}
private static RoutedCommand CreateCommand(string label)
{
return new RoutedCommand(label, typeof(MainWindow));
}
}
}
最佳答案
简单的解决方案
将输入绑定(bind)添加到 WebBrowser 控件以及主菜单:
Browser.InputBindings.Add(new KeyBinding(ApplicationCommands.Open,
new KeyGesture(Key.O, ModifierKeys.Control)));
硬解
这里发生的是 UIElement
正在使用 KeyDown
事件,而你想使用 PreviewKeyDown
事件,或者添加一个处理程序它还处理 Handled
路由事件。查找Tunnelling and Bubbling如果您对此一无所知。
由于这是在 UIElement 类中处理的,因此我建议在这种情况下使用不同的模式。 The MVVM Light framework提供 EventToCommand
行为。如果您可以将窗口的 PreviewKeyDown
事件路由到正确的命令,而不是将 KeyBinding
与 UIElement< 的
你会得到你的解决方案。InputBindings
集合一起使用
您将需要一些自定义代码来检查按下了哪个键以及应该路由到哪个命令。
关于c# - InputBinding 和 WebBrowser 控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8250136/