WPF में कीबोर्ड शॉर्टकट


129

मुझे _इसके बजाय उपयोग करने के बारे में पता है &, लेकिन मैं सभी Ctrl+ प्रकार के शॉर्टकट देख रहा हूं ।

Ctrl+ Zपूर्ववत् करने के लिए, Ctrl+ Sबचाने के लिए, आदि

क्या WPF अनुप्रयोगों में इन्हें लागू करने का कोई 'मानक' तरीका है? या क्या यह आपका अपना रोल है और जो भी कमांड / कंट्रोल करता है, उन्हें तार देता है?

जवाबों:


170

एक तरीका यह है कि अपने शॉर्टकट कीज को कमांड के रूप में खुद से जोड़ें InputGestures। कमांड के रूप में कार्यान्वित किए जाते हैं RoutedCommands

यह शॉर्टकट कुंजियों को काम करने में सक्षम बनाता है, भले ही वे किसी भी नियंत्रण के लिए आदी न हों। और जब से मेनू आइटम कीबोर्ड इशारों को समझते हैं, वे मेनू आइटम टेक्स्ट में स्वचालित रूप से आपकी शॉर्टकट कुंजी प्रदर्शित करेंगे, यदि आप उस मेनू को अपने मेनू आइटम पर हुक करते हैं।

  1. कमांड रखने के लिए स्टैटिक एट्रिब्यूट बनाएँ (अधिमानतः एक स्टैटिक क्लास में एक प्रॉपर्टी के रूप में, जो आप कमांड्स के लिए बनाते हैं - लेकिन एक साधारण उदाहरण के लिए, बस window.cs में स्टैटिक विशेषता का उपयोग करके):

     public static RoutedCommand MyCommand = new RoutedCommand();
  2. शॉर्टकट कुंजी जोड़ें जो विधि को लागू करना चाहिए:

     MyCommand.InputGestures.Add(new KeyGesture(Key.S, ModifierKeys.Control));
  3. एक कमांड बाइंडिंग बनाएं जो निष्पादित करने के लिए आपकी विधि को इंगित करता है। यूआई तत्व के लिए कमांड बाइंडिंग में रखें, जिसके तहत इसे काम करना चाहिए (जैसे, खिड़की) और विधि:

     <Window.CommandBindings>
         <CommandBinding Command="{x:Static local:MyWindow.MyCommand}" Executed="MyCommandExecuted"/>
     </Window.CommandBindings>
    
     private void MyCommandExecuted(object sender, ExecutedRoutedEventArgs e) { ... }

4
मैं मेनू आइटम के साथ कमांड को कैसे जोड़ूं? निश्चित रूप से यह इस उत्तर में शामिल करने के लिए सबसे महत्वपूर्ण जानकारी होगी, लेकिन यह गायब है।
टिमवी

8
@ टिमी: मैंने मौजूदा घटना में कीबोर्ड शॉर्टकट जोड़ने के लिए इस तरह से ऊपर दिए गए कोड का उपयोग किया है: RoutedCommand cmndSettings = new RoutedCommand (); cmndSettings.InputGestures.Add (नया KeyGesture (Key.S, ModifierKeys.Control)); CommandBindings.Add (नई CommandBinding (cmndSettings, mnuSettings_Click));
इसकी १

1
itho की टिप्पणी ने मेरे लिए यह काम कर दिया, काम के ऊपर xml कोड नहीं बना सका।
गोसर

1
दुर्भाग्य से, इस दृष्टिकोण के साथ, Executedकमांड के लिए कोड दृश्य-मॉडल के बजाय कोड-पीछे (विंडो या उपयोगकर्ता-नियंत्रण) में समाप्त हो जाएगा, जैसा कि एक सामान्य कमांड (कस्टम ICommandकार्यान्वयन) का उपयोग करने के विपरीत है ।
या मैपर


97

मुझे यह ठीक वैसा ही लगा जैसा कि मैं WPF में कुंजी बंधन से संबंधित देख रहा था:

<Window.InputBindings>
        <KeyBinding Modifiers="Control"
                    Key="N"
                    Command="{Binding CreateCustomerCommand}" />
</Window.InputBindings>

ब्लॉग पोस्ट देखें MVVM CommandReference और KeyBinding


बहुत अच्छा और आसान!
विलय

1
क्या आप "CreateCustomerCommand" पर विस्तार से विचार करेंगे और इसे कैसे लागू किया जाना है?
विन्ज

यह अभी भी एक लिंक केवल उत्तर है क्योंकि कॉपी और पेस्ट किए गए कोड स्निपेट को लिंक किए गए ब्लॉग पोस्ट पर "परिणाम एक अपवाद होगा" के साथ वर्णित किया गया है। : पी
मार्टिन श्नाइडर

यहां चमत्कार काम करता है। मैंने पहली बार ओपी की तरह बटन सामग्री की कुंजी से पहले "_" जोड़ने की कोशिश की, लेकिन यह काम नहीं किया। सबसे खराब, यह तब सक्रिय हुआ जब मैंने कुंजी को स्वयं मारा जब मैं इंटरफ़ेस की एक लिखने योग्य वस्तु पर ध्यान केंद्रित नहीं कर रहा था .. जैसे कि ctrl-s के बजाय "s" सेव के लिए।
जय

14

इस कोड को आज़माएं ...

सबसे पहले एक RoutedComand ऑब्जेक्ट बनाएं

  RoutedCommand newCmd = new RoutedCommand();
  newCmd.InputGestures.Add(new KeyGesture(Key.N, ModifierKeys.Control));
  CommandBindings.Add(new CommandBinding(newCmd, btnNew_Click));

9

यह इस बात पर निर्भर करता है कि आप उन का उपयोग कहां करना चाहते हैं।

TextBoxBaseनियंत्रित नियंत्रण पहले से ही उन शॉर्टकटों को लागू करते हैं। यदि आप कस्टम कीबोर्ड शॉर्टकट का उपयोग करना चाहते हैं तो आपको कमांड और इनपुट इशारों पर एक नज़र डालनी चाहिए। यहाँ से एक छोटा ट्यूटोरियल है कोड पर स्विच : WPF ट्यूटोरियल - कमांड बाइंडिंग और कस्टम कमांड


8
क्या एक बकवास ट्यूटोरियल - सभी की सबसे महत्वपूर्ण बात की व्याख्या नहीं करता है, जो कि कैसे एक कमांड का उपयोग करना है जो कि 20 "सामान्य" कमांड के अपने पूर्वनिर्धारित सेट में से एक नहीं होता है।
टिमवी

6

दूसरों के लिए इस उत्तर का दस्तावेजीकरण करना, क्योंकि ऐसा करने का एक बहुत सरल तरीका है जो शायद ही कभी संदर्भित होता है, और XAML को छूने की आवश्यकता नहीं होती है।

एक कीबोर्ड शॉर्टकट को लिंक करने के लिए, विंडो कंस्ट्रक्टर में, इनपुटबाइंडिंग संग्रह में एक नया कीबाइंडिंग जोड़ें। कमांड के रूप में, अपनी मनमानी कमांड क्लास में पास करें जो ICommand को लागू करती है। निष्पादित विधि के लिए, आपको जो भी तर्क की आवश्यकता है, उसे लागू करें। नीचे मेरे उदाहरण में, मेरा WindowCommand वर्ग एक प्रतिनिधि लेता है कि जब भी इसे लागू किया जाएगा। जब मैं अपनी बाइंडिंग के साथ पास करने के लिए नए WindowCommand का निर्माण करता हूं, तो मैं बस अपने इनिशियलाइज़र में इंगित करता हूं, वह विधि जिसे मैं WindowCommand निष्पादित करना चाहता हूं।

आप अपने खुद के त्वरित कीबोर्ड शॉर्टकट के साथ आने के लिए इस पैटर्न का उपयोग कर सकते हैं।

public YourWindow() //inside any WPF Window constructor
{
   ...
   //add this one statement to bind a new keyboard command shortcut
   InputBindings.Add(new KeyBinding( //add a new key-binding, and pass in your command object instance which contains the Execute method which WPF will execute
      new WindowCommand(this)
      {
         ExecuteDelegate = TogglePause //REPLACE TogglePause with your method delegate
      }, new KeyGesture(Key.P, ModifierKeys.Control)));
   ...
}

एक सरल WindowCommand वर्ग बनाएं जो उस पर सेट किसी भी विधि को आग लगाने के लिए एक निष्पादन प्रतिनिधि लेता है।

public class WindowCommand : ICommand
{
    private MainWindow _window;

    //Set this delegate when you initialize a new object. This is the method the command will execute. You can also change this delegate type if you need to.
    public Action ExecuteDelegate { get; set; }

    //You don't have to add a parameter that takes a constructor. I've just added one in case I need access to the window directly.
    public WindowCommand(MainWindow window)
    {
        _window = window;
    }

    //always called before executing the command, mine just always returns true
    public bool CanExecute(object parameter)
    {
        return true; //mine always returns true, yours can use a new CanExecute delegate, or add custom logic to this method instead.
    }

    public event EventHandler CanExecuteChanged; //i'm not using this, but it's required by the interface

    //the important method that executes the actual command logic
    public void Execute(object parameter)
    {
        if (ExecuteDelegate != null)
        {
            ExecuteDelegate();
        }
        else
        {
            throw new InvalidOperationException();
        }
    }
}

5

मुझे भी इसी तरह की समस्या थी और इसमें @ अलीवा का जवाब सबसे उपयोगी और सबसे सुंदर समाधान था; हालाँकि, मुझे एक विशिष्ट कुंजी संयोजन की आवश्यकता थी, Ctrl+ 1। दुर्भाग्य से मुझे निम्नलिखित त्रुटि मिली:

'1' का उपयोग 'की' के लिए मान के रूप में नहीं किया जा सकता है। नंबर मान्य गणना मूल्य नहीं हैं।

आगे की खोज के साथ, मैंने @ अलीवा के उत्तर को निम्नलिखित में संशोधित किया:

<Window.InputBindings>
    <KeyBinding Gesture="Ctrl+1" Command="{Binding MyCommand}"/>
</Window.InputBindings>

मुझे यह बहुत अच्छी तरह से किसी भी संयोजन के लिए महान काम करने के लिए मिला जिसकी मुझे आवश्यकता थी।


इसने मेरे लिए काम किया<UserControl.InputBindings> <KeyBinding Gesture="Enter" Command="{Binding someCommand}"/> </UserControl.InputBindings>
fs_tigre

3

VB.NET:

Public Shared SaveCommand_AltS As New RoutedCommand

भरी हुई घटना के अंदर :

SaveCommand_AltS.InputGestures.Add(New KeyGesture(Key.S, ModifierKeys.Control))

Me.CommandBindings.Add(New CommandBinding(SaveCommand_AltS, AddressOf Me.save))

कोई XAML की जरूरत नहीं है।


1

यद्यपि शीर्ष उत्तर सही हैं, मैं व्यक्तिगत रूप से संलग्न गुणों के साथ काम करना पसंद करता हूं ताकि समाधान को किसी भी पर लागू किया जा सके UIElement, खासकर जबWindow तत्व के बारे में पता नहीं है जिसे ध्यान केंद्रित किया जाना चाहिए। अपने अनुभव में मैं अक्सर कई दृश्य मॉडल और उपयोगकर्ता नियंत्रणों की एक संरचना देखता हूं, जहां खिड़की अक्सर रूट कंटेनर से ज्यादा कुछ नहीं होती है।

टुकड़ा

public sealed class AttachedProperties
{
    // Define the key gesture type converter
    [System.ComponentModel.TypeConverter(typeof(System.Windows.Input.KeyGestureConverter))]
    public static KeyGesture GetFocusShortcut(DependencyObject dependencyObject)
    {
        return (KeyGesture)dependencyObject?.GetValue(FocusShortcutProperty);
    }

    public static void SetFocusShortcut(DependencyObject dependencyObject, KeyGesture value)
    {
        dependencyObject?.SetValue(FocusShortcutProperty, value);
    }

    /// <summary>
    /// Enables window-wide focus shortcut for an <see cref="UIElement"/>.
    /// </summary>
    // Using a DependencyProperty as the backing store for FocusShortcut.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty FocusShortcutProperty =
        DependencyProperty.RegisterAttached("FocusShortcut", typeof(KeyGesture), typeof(AttachedProperties), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.None, new PropertyChangedCallback(OnFocusShortcutChanged)));

    private static void OnFocusShortcutChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (!(d is UIElement element) || e.NewValue == e.OldValue)
            return;

        var window = FindParentWindow(d);
        if (window == null)
            return;

        var gesture = GetFocusShortcut(d);
        if (gesture == null)
        {
            // Remove previous added input binding.
            for (int i = 0; i < window.InputBindings.Count; i++)
            {
                if (window.InputBindings[i].Gesture == e.OldValue && window.InputBindings[i].Command is FocusElementCommand)
                    window.InputBindings.RemoveAt(i--);
            }
        }
        else
        {
            // Add new input binding with the dedicated FocusElementCommand.
            // see: https://gist.github.com/shuebner20/349d044ed5236a7f2568cb17f3ed713d
            var command = new FocusElementCommand(element);
            window.InputBindings.Add(new InputBinding(command, gesture));
        }
    }
}

इस संलग्न संपत्ति के साथ आप किसी भी UIElement के लिए फ़ोकस शॉर्टकट को परिभाषित कर सकते हैं। यह स्वचालित रूप से तत्व वाले विंडो में इनपुट बाइंडिंग को पंजीकृत करेगा।

उपयोग (XAML)

<TextBox x:Name="SearchTextBox"
         Text={Binding Path=SearchText}
         local:AttachedProperties.FocusShortcutKey="Ctrl+Q"/>

सोर्स कोड

फ़ोकसमेंटमेंटकमांड कार्यान्वयन सहित पूरा नमूना जिस्ट के रूप में उपलब्ध है: https://gist.github.com/shuebner20/c6a5191be23da549d5004ee56bcc352d

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


-2

कैसे एक के साथ कमान संबद्ध करने के लिए MenuItem:

<MenuItem Header="My command" Command="{x:Static local:MyWindow.MyCommand}"/>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.