Элемент управления InputBinding и WebBrowser
У меня есть очень простое приложение, в котором я пытаюсь связать сочетания клавиш с командой WPF, связанной с пунктом меню. Само приложение состоит только из Menu
и WebBrowser
контроль.
Когда я в пределах WebBrowser
сочетания клавиш не перенаправляются в меню WPF. Например, нажатие клавиши Ctrl+O, когда вы находитесь в веб-браузере, показывает открытую страницу IE. Кроме того, в этом приложении, если у меня нет меню (с помощью Alt), привязки ввода не срабатывают. Например, я не могу сосредоточиться на окне 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));
}
}
}
1 ответ
Простое решение
Добавьте привязки ввода в элемент управления WebBrowser, а также в главное меню:
Browser.InputBindings.Add(new KeyBinding(ApplicationCommands.Open,
new KeyGesture(Key.O, ModifierKeys.Control)));
Трудное решение
Здесь происходит то, что UIElement
использует KeyDown
событие, пока вы хотите использовать PreviewKeyDown
событие или добавить обработчик, который также обрабатывает Handled
перенаправленные события. Посмотрите на Tunneling and Bubbling, если вы не знаете об этом.
Поскольку это обрабатывается в классе UIElement, я бы посоветовал использовать другой шаблон в этой ситуации. Каркас MVVM Light обеспечивает EventToCommand
поведение. Если вы можете направить PreviewKeyDown
Событие окна справа команды вместо использования KeyBinding
с InputBindings
коллекция UIElement
у вас будет свое решение.
Вам понадобится некоторый пользовательский код, чтобы проверить, какая клавиша была нажата и какой команде должна быть выполнена маршрутизация.