2011-03-16 24 views
5

मैं MenuItem के लिए कीबोर्ड शॉर्टकट लागू करना चाहता हूं। मैं नीचे दिए गए कोड का इस्तेमाल किया है:मेनू Item.InputGestureText को क्यों सेट नहीं करता है जब मैं इनपुट इशारा करता हूं तो मेनूइटम सक्रिय होता है?

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

लेकिन InputGestureText संपत्ति प्रतिसाद नहीं दे रहा है जब मैं CTRL+N दबाया। मैं विजुअल स्टूडियो एक्सप्रेस संस्करण 2010 का उपयोग कर रहा हूं। क्या मुझे यहां कुछ याद आ रही है?

उत्तर

9

यह संपत्ति के लिए दस्तावेज में काफी स्पष्ट है:

यह गुण मेनू आइटम के साथ इनपुट इशारा संबद्ध नहीं करता है; यह बस मेनू आइटम में टेक्स्ट जोड़ता है। एप्लिकेशन को कार्रवाई करने के लिए उपयोगकर्ता के इनपुट को संभालना होगा। के लिए मेनू आइटम के साथ कमांड को संबद्ध करने के तरीके के बारे में जानकारी, Command देखें।

4

यह करने के लिए सबसे अच्छा तरीका है एक Command बनाने, और कहा कि आदेश के साथ InputGesture संबद्ध करने के लिए है:

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) 
{ 
    ... 
} 

तुम सच में सिर्फ एक "नया" आदेश चाहते हैं, आप RoutedCommand बनाने को छोड़ सकते हैं और InputGesture, क्योंकि उस आदेश पहले से ही आप के लिए बनाई गई है:

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

... 

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

... 

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

एक समाधान है कि आदेश और बाइंडिंग को शामिल नहीं करता, स्वामित्व वाली ओवरराइड करने के लिए है विंडो की OnKeyDown विधि और उस मेनू आइटम को खोजें जिसमें KeyGesture है जो कीबोर्ड ईवेंट से मेल खाता है। यहाँ

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

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

और उपयोगिता कोड है कि कुंजीपटल घटना के साथ एक मेनू आइटम से मेल खाता है:

यहाँ खिड़की के OnKeyDown ओवरराइड के लिए कोड है

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; 
     } 
    } 
संबंधित मुद्दे

 संबंधित मुद्दे