प्रपत्र KeyDown घटनाओं का जवाब नहीं


82

मैं अपने विंडोज फॉर्म प्रोजेक्ट पर कुछ समय से काम कर रहा हूं, और मैंने कीबोर्ड शॉर्टकट के साथ प्रयोग करने का फैसला किया है। थोड़ा पढ़ने के बाद, मुझे लगा कि मुझे सिर्फ एक इवेंट हैंडलर लिखना है और इसे फ़ॉर्म की कीडाउन इवेंट में बाँध देना है:

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Control && e.Alt && e.KeyCode == Keys.O)
    {
        MessageBox.Show("Ctrl+Alt+O: magic!");
    }
}

मैंने विजुअल स्टूडियो डिज़ाइनर के गुण पैनल को खोलने का अच्छा राजभाषा तरीका अपनाया, फिर Form1_KeyDownइवेंट हैंडलर को बनाने के लिए मेरे फॉर्म के कीडाउन इवेंट पर डबल-क्लिक किया । लेकिन मेरे आवेदन का परीक्षण करने पर, प्रपत्र Ctrl+ Alt+ Oकीबोर्ड शॉर्टकट पर बिल्कुल भी प्रतिक्रिया नहीं देता है । विज़ुअल स्टूडियो डिज़ाइनर ने इवेंट हैंडलर को फॉर्म में बाँधने के लिए कोड उत्पन्न किया है:

private void InitializeComponent()
{
    // ...

    this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);

    // ...
}

इसलिए मैंने Console.WriteLine()हैंडलर को यह जाँचने के लिए एक कॉल जोड़ने की कोशिश की कि यह बिल्कुल भी कॉल किया जा रहा है, लेकिन उस पर कोई भाग्य नहीं।

इसके अलावा, मैंने इवेंट बाइंडिंग कॉल (ऊपर दिखाया गया है) पर एक ब्रेकपॉइंट सेट करने की कोशिश की और पाया कि प्रोग्राम उस ब्रेकपॉइंट पर ठीक पहुंचता है। लेकिन किसी भी ब्रेकप्वाइंट को मैंने विधि परिभाषा के भीतर ही सेट किया है, कभी नहीं पहुंचा।

यह सुनिश्चित करने के लिए कि मैं पहले कुछ कदम सही ढंग से कर रहा था, मैंने उन्हें दोहराने की कोशिश की:

  • उसी समाधान में एक नया रूप।
    एक ही मुद्दा: जब मैं मेरा Ctrl+ Alt+ Oकीबोर्ड शॉर्टकट दबाता हूं तो फॉर्म प्रतिक्रिया नहीं देता है और डिबगर ईवेंट हैंडलर में भी कदम नहीं रख रहा है। फिर से कोशिश की और यह काम करता है।

  • एक नया WinForms समाधान।
    यह पूरी तरह से काम करता है: संदेश संवाद प्रकट होता है ( Console.WriteLine()कॉल भी काम करता है)।

इसलिए मैं यहां काफी खो गया हूं। KeyDown ईवेंट प्राप्त करने से इस एक प्रोजेक्ट के सभी फ़ॉर्म क्या रोक रहे हैं?

जवाबों:


174

क्या आपके फॉर्म में KeyPreview प्रॉपर्टी सही है?

फॉर्म.केप्रिव्यू प्रॉपर्टी

हो जाता है या यह दर्शाता है कि घटना के नियंत्रण में फ़ोकस होने से पहले प्रपत्र को प्रमुख घटनाएँ मिलेंगी या नहीं, यह दर्शाता है।

http://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview.aspx


19
यह एक हैक है, जिसे VB6 प्रोग्रामर को खुश रखने के लिए उपलब्ध कराया गया है। इसमें ऑर्डर-ऑफ-एग्जीक्यूटिव प्रॉब्लम्स हैं, इसके बजाय ProcessCmdKey () को ओवरराइड करें।
हंस पैसेंट जूल

@ हंसपसंद, मुझे आदेश-निष्पादन की समस्याओं के बारे में बताने के लिए कुछ भी नहीं मिल रहा है। KeyDown + KeyPreview सभी कुंजियों को नहीं देखेगा, जो एक समस्या के लिए पर्याप्त है, लेकिन निष्पादन आदेश की समस्याएं क्या हैं?
kdbanman

1
शॉर्टकट कीस्ट्रोक्स का पता लगाने के लिए बहुत सारे ओवरराइड हैं। आदेश में निष्पादित, KeyPreview + KeyDown अंतिम है।
हंस पसंत

54

StackOverflow और MSDN 1 , 2 (यहां स्वीकृत उत्तर सहित) पर इस समस्या के लिए सबसे आम सलाह त्वरित और आसान है:

KeyDownFormजब तक इसकी KeyPreviewसंपत्ति सेट की जाती है, तब तक घटनाओं को ट्रिगर किया जाता हैtrue

यह अधिकांश उद्देश्यों के लिए पर्याप्त है, लेकिन यह दो कारणों से जोखिम भरा है:

  1. KeyDownहैंडलर सभी चाबियों को नहीं देखते हैं । विशेष रूप से, "आप नेविगेशन के लिए उपयोग किए जाने वाले कीस्ट्रोक्स को नहीं देख सकते। कर्सर कुंजी और टैब की तरह, एस्केप और एक डायलॉग के लिए दर्ज करें।"

  2. महत्वपूर्ण घटनाओं को रोकने के लिए कुछ अलग तरीके हैं, और वे सभी अनुक्रम में होते हैं। अंतिमKeyDown संभाला है । इसलिए, पूर्वावलोकन बहुत ज्यादा नहीं है, और रास्ते में कुछ स्टॉप पर घटना को शांत किया जा सकता है।KeyPreview

(उन बिंदुओं के लिए @HansPassant को श्रेय।)

इसके बजाय, ProcessCmdKeyअपने में ओवरराइड करें Form:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
    if (keyData == Keys.Up)
    {
        // Handle key at form level.
        // Do not send event to focused control by returning true.
        return true;
    }
  return base.ProcessCmdKey(ref msg, keyData);
}

इस तरह, सभी कुंजियाँ विधि को दिखाई देती हैं, और विधि घटना को देखने के लिए पहली पंक्ति में है।

ध्यान दें कि आपके पास अभी भी नियंत्रण है कि केंद्रित नियंत्रण KeyDownघटना को देखता है या नहीं । बस trueबाद की KeyDownघटना को अवरुद्ध करने के लिए लौटें , बजाय सेटिंग KeyPressEventArgs.Handledके trueआप एक KeyDownइवेंट हैंडलर में होंगे। यहाँ अधिक विवरण के साथ एक लेख है।


1
यह सही उत्तर है, खासकर यदि आपको लगता है कि PreviewKeyDown सही पर सेट कीपरव्यू के साथ आग नहीं देगा।
टिम

23

KeyPreviewअपने फ़ॉर्म को सही पर सेट करने का प्रयास करें । इसने मेरे लिए प्रमुख प्रेसों को पंजीकृत करने के लिए काम किया।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.