【问题标题】:InputBinding and WebBrowser controlInputBinding 和 WebBrowser 控件
【发布时间】:2012-01-05 05:08:21
【问题描述】:

我有一个非常简单的应用程序,我试图将键盘快捷键绑定到绑定到菜单项的 WPF 命令。应用程序本身只包含一个Menu 和一个WebBrowser 控件。

当我在 WebBrowser 中时,键盘快捷键不会路由到 WPF 菜单。例如,在 Web 浏览器中聚焦时键入“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));
        }
    }
}

【问题讨论】:

    标签: c# wpf menu commandbinding inputbinding


    【解决方案1】:

    简单的解决方案

    将输入绑定添加到 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 集合一起使用,您将获得您的解决方案。

    您将需要一些自定义代码来检查按下了哪个键以及路由应该是哪个命令。

    【讨论】:

    • 这主要是我想要的,除非焦点不在浏览器或菜单上。我尝试将命令绑定添加到 MainWindow,但这也无济于事。在上面的示例中,例如(在将绑定添加到浏览器控件之后),如果我输入其中一个命令(弹出一个消息框)然后单击回车,我将无法再执行任何快捷方式,直到我单击再次在浏览器控件中。
    • 尝试将它们添加到浏览器和主窗口中!
    • 我确实将它们添加到浏览器和主窗口以及菜单中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-28
    • 2010-09-10
    • 2023-04-05
    • 2010-11-28
    相关资源
    最近更新 更多