2011-03-16 40 views
5

Tôi muốn triển khai phím tắt cho một số MenuItem. Tôi đã sử dụng mã bên dưới:Tại sao không đặt MenuItem.InputGestureText khiến MenuItem kích hoạt khi tôi thực hiện thao tác nhập?

<MenuItem Header="_New" InputGestureText="CTRL+N" Click="NewMenu_Click"> 
    <MenuItem.Icon> 
     <Image Source= "Images\NEW.PNG" Width="25" Height="28" /> 
    </MenuItem.Icon> 
</MenuItem>` 

Nhưng InputGestureText bất động sản không được đáp ứng khi tôi nhấn CTRL+N. Tôi đang sử dụng Visual Studio Express Edition 2010. Tôi có thiếu gì ở đây không?

Trả lời

9

Nó là khá rõ ràng trong tài liệu cho bất động sản:

Khách sạn này không kết hợp cử chỉ đầu vào với mục trình đơn; nó chỉ cần thêm văn bản vào mục menu. Ứng dụng phải xử lý đầu vào của người dùng để thực hiện hành động. Để biết thông tin về về cách liên kết lệnh với một mục menu, hãy xem Command.

4

Cách tốt nhất để làm điều này là để thực hiện một Command, và kết hợp InputGesture với lệnh rằng:

public static class Commands 
{ 
    public static readonly RoutedCommand CreateNew = new RoutedCommand("New", typeof(Commands)); 

    static Commands() 
    { 
     SomeCommand.InputGestures.Add(new KeyGesture(Key.N, ModifierKeys.Control)); 
    } 
} 

... 

// Wherever you want to create the MenuItem. "local" should be the namespace that 
// you delcared "Commands" in. 
<MenuItem Header="_New" Command="{x:Static local:Commands.CreateNew}"> 

... 

// Wherever you want to process the command. I am assuming you want to do it in your 
// main window, but you can do it anywhere in the route between your main window and 
// the menu item. 
<Window.CommandBindings> 
    <CommandBinding Command="{x:Static local:Commands.CreateNew}"> Executed="CreateNew_Executed" /> 
</Window.CommandBindings> 

... 

// In the code behind for your main window (or whichever file you put the above XAML in) 
private void CreateNew(object sender, ExecutedRoutedEventArgs e) 
{ 
    ... 
} 

Nếu bạn thực sự chỉ muốn có một lệnh "New", bạn có thể bỏ qua việc tạo ra các RoutedCommandInputGesture, vì lệnh đó đã được tạo cho bạn:

<MenuItem Header="_New" Command="New"> 

... 

<Window.CommandBindings> 
    <CommandBinding Command="New" Executed="New_Executed" /> 
</Window.CommandBindings> 

... 

private void New_Executed(object sender, ExecutedRoutedEventArgs e) 
{ 
    ... 
} 
2

Một giải pháp không liên quan đến lệnh và ràng buộc là ghi đè quyền sở hữu Phương thức OnKeyDown của Cửa sổ và tìm kiếm mục menu có KeyGesture khớp với sự kiện bàn phím.

Đây là mã cho ghi đè onKeyDown của Window:

protected override void OnKeyDown(KeyEventArgs e) 
{ 
    base.OnKeyDown(e); 

    // here I suppose the window's menu is named "MainMenu" 
    MainMenu.RaiseMenuItemClickOnKeyGesture(e); 
} 

Và đây là mã tiện ích phù hợp với một mục trình đơn với sự kiện bàn phím:

public static void RaiseMenuItemClickOnKeyGesture(this ItemsControl control, KeyEventArgs args) => RaiseMenuItemClickOnKeyGesture(control, args, true); 
    public static void RaiseMenuItemClickOnKeyGesture(this ItemsControl control, KeyEventArgs args, bool throwOnError) 
    { 
     if (args == null) 
      throw new ArgumentNullException(nameof(args)); 

     if (control == null) 
      return; 

     var kgc = new KeyGestureConverter(); 
     foreach (var item in control.Items.OfType<MenuItem>()) 
     { 
      if (!string.IsNullOrWhiteSpace(item.InputGestureText)) 
      { 
       KeyGesture gesture = null; 
       if (throwOnError) 
       { 
        gesture = kgc.ConvertFrom(item.InputGestureText) as KeyGesture; 
       } 
       else 
       { 
        try 
        { 
         gesture = kgc.ConvertFrom(item.InputGestureText) as KeyGesture; 
        } 
        catch 
        { 
        } 
       } 

       if (gesture != null && gesture.Matches(null, args)) 
       { 
        item.RaiseEvent(new RoutedEventArgs(MenuItem.ClickEvent)); 
        args.Handled = true; 
        return; 
       } 
      } 

      RaiseMenuItemClickOnKeyGesture(item, args, throwOnError); 
      if (args.Handled) 
       return; 
     } 
    } 
Các vấn đề liên quan