Элемент управления 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 у вас будет свое решение.

Вам понадобится некоторый пользовательский код, чтобы проверить, какая клавиша была нажата и какой команде должна быть выполнена маршрутизация.

Другие вопросы по тегам