विंडोज फॉर्मेट्स एप्लिकेशन में कीबोर्ड शॉर्टकट को लागू करने का सबसे अच्छा तरीका?


280

मैं आम Windows कीबोर्ड शॉर्टकट लागू करने के लिए एक सबसे अच्छा तरीका है के लिए देख रहा हूँ (उदाहरण के लिए Ctrl+ F, Ctrl+ Nमेरे में) Windows Forms सी # में आवेदन।

एप्लिकेशन का एक मुख्य रूप है जो कई बच्चे रूपों (एक समय में एक) को होस्ट करता है। जब कोई उपयोगकर्ता Ctrl+ हिट करता है F, तो मैं एक कस्टम खोज फ़ॉर्म दिखाना चाहता हूं। खोज फॉर्म आवेदन में वर्तमान ओपन चाइल्ड फॉर्म पर निर्भर करेगा।

मैं ChildForm_KeyDown घटना में कुछ इस तरह का उपयोग करने के बारे में सोच रहा था :

   if (e.KeyCode == Keys.F && Control.ModifierKeys == Keys.Control)
        // Show search form

लेकिन यह काम नहीं करता है। जब आप किसी कुंजी को दबाते हैं तो यह घटना भी आग नहीं लगाती है। उपाय क्या है?


यह वास्तव में अजीब है कि Winforms को इसके लिए विशिष्ट कार्यक्षमता नहीं लगती है जैसे कि देशी Windows API करता है।
स्टीवर्ट

जवाबों:


460

आप शायद True पर फ़ॉर्म की KeyPreview प्रॉपर्टी सेट करना भूल गए हैं। ProcessCmdKey () विधि को ओवरराइड करना जेनेरिक समाधान है:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
  if (keyData == (Keys.Control | Keys.F)) {
    MessageBox.Show("What the Ctrl+F?");
    return true;
  }
  return base.ProcessCmdKey(ref msg, keyData);
}

यह अच्छी तरह से काम करता है, लेकिन केवल मेरे लिए इसका पता लगाता है यदि प्रपत्र सक्रिय विंडो है। किसी को पता है कि यह किसी भी खिड़की दृश्य में यह कैसे संभव है बांधने के लिए?
Ga

कुछ स्थितियों KeyPreviewमें काफी अपरिहार्य है। उदाहरण के लिए, जब एक शॉर्टकट दबाने पर इनपुट को दबाने की आवश्यकता होती है, लेकिन फिर भी एक अलग MenuStripघटना को आग लगाने की अनुमति नहीं होती है । ProcessCmdKeyदृष्टिकोण घटना फायरिंग तर्क के दोहराव को मजबूर करेगा।
शाऊल

1
हम्म, नहीं, फॉर्म की कीडाउन इवेंट हैंडलर मेनू आइटम के क्लिक इवेंट हैंडलर से काफी अलग है। आप अभी भी ठीक उसी तरह से करते हैं, या तो सीधे ईवेंट हैंडलर विधि को कॉल करें (इसके लिए विशेष रूप से किसी ईवेंट द्वारा कॉल करने की कोई आवश्यकता नहीं है) या आम लॉजिक को एक अलग तरीके से रीफैक्टर करें।
हंस पैसिव

14
"क्या Ctrl + F?" LOL
kchad

73

अपने मुख्य रूप पर

  1. KeyPreviewसही पर सेट करें
  2. निम्नलिखित कोड के साथ KeyDown इवेंट हैंडलर जोड़ें

    private void MainForm_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Control && e.KeyCode == Keys.N)
        {
            SearchForm searchForm = new SearchForm();
            searchForm.Show();
        }
    }

4
+ के लिए, सेट KeyPreview ट्रू करने के लिए .. गायब था कि
उस्मान

20

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


1
समस्या यह है कि मुख्य प्रपत्र सामान्य विंडोज़ मेनू का उपयोग नहीं करता है। यह कस्टम नेविगेशन पैनल का उपयोग करता है जिसका उपयोग बाल रूपों को दिखाने के लिए किया जाता है। खोज प्रपत्र बच्चे के रूप में ToolStripButton पर क्लिक करके मंगवाए गए हैं।
रॉककोडर

menu mnemonicsअसली नमूना?
किकेनेट


1
शॉर्टकट कीज़ से Mememonics एक अलग अवधारणा है, और वे कैसे काम करते हैं, इसमें महत्वपूर्ण अंतर हैं। संक्षेप में, mnemonics मेनू का उपयोग करने के लिए मेनू, मेनू कमांड और संवाद नियंत्रण का उपयोग करने के लिए उपयोग किए जाने वाले रेखांकित वर्ण हैं। OTOH, शॉर्टकट कुंजियाँ मेन्यू से गुजरे बिना कमांड एक्सेस करने का एक तरीका है, और इसके अलावा वे Ctrl + F या F5 जैसे मनमाने ढंग से कीस्ट्रोक्स हो सकते हैं, चरित्र कुंजियों तक सीमित नहीं हैं।
स्टीवर्ट

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

11

आप भी इस उदाहरण की कोशिश कर सकते हैं:

public class MDIParent : System.Windows.Forms.Form
{
    public bool NextTab()
    {
         // some code
    }

    public bool PreviousTab()
    {
         // some code
    }

    protected override bool ProcessCmdKey(ref Message message, Keys keys)
    {
        switch (keys)
        {
            case Keys.Control | Keys.Tab:
              {
                NextTab();
                return true;
              }
            case Keys.Control | Keys.Shift | Keys.Tab:
              {
                PreviousTab();
                return true;
              }
        }
        return base.ProcessCmdKey(ref message, keys);
    }
}

public class mySecondForm : System.Windows.Forms.Form
{
    // some code...
}

8

यदि आपके पास एक मेनू है, तो ShortcutKeysसंपत्ति की बदलती ToolStripMenuItemचाल को करना चाहिए।

यदि नहीं, तो आप एक बना सकते हैं और इसकी visibleसंपत्ति को झूठा कर सकते हैं।


नहीं, मेरे पास मेनू नहीं है। टूलस्ट्रिपबटन खोज के लिए वास्तव में बाइंडिंगनिगेटर नियंत्रण पर स्थित है, इसलिए मेनू जोड़ना संभवतः एक विकल्प नहीं है।
रॉककोडर 16

6

मुख्य फॉर्म से, आपको निम्न करना होगा:

  • सुनिश्चित करें कि आपने KeyPreview को सही पर सेट किया है (डिफ़ॉल्ट रूप से TRUE)
  • MainForm_KeyDown (..) जोड़ें - जिसके द्वारा आप यहां अपनी इच्छानुसार कोई भी शॉर्टकट सेट कर सकते हैं।

इसके अतिरिक्त, मैंने इसे Google पर पाया है और मैं इसे उन लोगों को साझा करना चाहता था जो अभी भी उत्तर खोज रहे हैं। (वैश्विक के लिए)

मुझे लगता है कि आपको user32.dll का उपयोग करना होगा

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);

    if (m.Msg == 0x0312)
    {
        /* Note that the three lines below are not needed if you only want to register one hotkey.
         * The below lines are useful in case you want to register multiple keys, which you can use a switch with the id as argument, or if you want to know which key/modifier was pressed for some particular reason. */

        Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);                  // The key of the hotkey that was pressed.
        KeyModifier modifier = (KeyModifier)((int)m.LParam & 0xFFFF);       // The modifier of the hotkey that was pressed.
        int id = m.WParam.ToInt32();                                        // The id of the hotkey that was pressed.


        MessageBox.Show("Hotkey has been pressed!");
        // do something
    }
}

इसके अलावा इसे पढ़ें http://www.fluxbytes.com/csharp/how-to-register-a-global-hotkey-for-your-application-in-c/


4

किसी के लिए हंस का जवाब थोड़ा आसान हो सकता है, इसलिए यहां मेरा संस्करण है।

आपको मूर्ख बनाने की आवश्यकता नहीं है KeyPreview, इसे सेट करने के लिए छोड़ दें false। नीचे दिए गए कोड का उपयोग करने के लिए, बस इसे अपने नीचे चिपकाएँ form1_loadऔर F5इसे देखने के लिए दौड़ें :

protected override void OnKeyPress(KeyPressEventArgs ex)
{
    string xo = ex.KeyChar.ToString();

    if (xo == "q") //You pressed "q" key on the keyboard
    {
        Form2 f2 = new Form2();
        f2.Show();
    }
}

7
सबसे पहले, OverCiding ProcessCmdKey एक कीस्ट्रोक से निपटने का अनुशंसित तरीका है जो कुछ कमांड-जैसे ऑपरेशन करने का इरादा रखता है, जो कि ओपी के बारे में पूछ रहा था। दूसरा, आपने KeyPreview को सच करने के बारे में हंस की टिप्पणी को गलत समझा है; वह सिर्फ ओपी को बता रहा था कि उसकी तकनीक काम क्यों नहीं कर रही है। ProcessCmdKey का उपयोग करने के लिए KeyPreview को सही पर सेट करना आवश्यक नहीं है।
RenniePet

2

WinForm में, हम हमेशा नियंत्रण कुंजी का दर्जा प्राप्त कर सकते हैं:

bool IsCtrlPressed = (Control.ModifierKeys & Keys.Control) != 0;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.