2011-11-23 70 views
3

我有一個非常簡單的應用程序,我嘗試將鍵盤快捷鍵綁定到綁定到菜單項的WPF命令。應用程序本身只包含一個MenuWebBrowser控件。InputBinding和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)); 
     } 
    } 
} 

回答

2

簡單的解決方案

添加輸入綁定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事件路由到正確的命令,而不是使用KeyBindingInputBindings集合UIElement,您將得到您的解決方案。

您將需要一些自定義代碼來檢查哪個鍵被按下以及路由應該使用哪個命令。

+0

這主要是我想要的,除非焦點不在瀏覽器或菜單上。我嘗試添加命令綁定到MainWindow,但也沒有幫助。在上面的示例中(例如,在向瀏覽器控件添加綁定之後),如果我鍵入其中一個命令(彈出一個消息框),然後單擊enter,我將不能再執行任何更多快捷方式,直到單擊在瀏覽器內再次控制。 – sohum

+0

嘗試將它們添加到瀏覽器和主窗口! – Bas

+0

我確實將它們添加到瀏覽器和主窗口以及菜單中。 – sohum