2009-10-29 20 views
57

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

मैंने प्रत्येक नियंत्रण चुड़ैल के लिए झंडे को टैबस्टॉप सेट किया है, एक पैनल को छोड़कर फोकस ले सकता है (लेकिन मुझे नहीं पता कि इसका असर पड़ता है)।

मैंने कुंजीप्रेव्यू को सत्य पर सेट किया है और मैं इस फॉर्म पर कीडाउन ईवेंट को प्रबंधित कर रहा हूं।

  • keydown गतिविधि सक्रिय नहीं है जब मैं केवल एक तीर कुंजी दबाने:

    मेरे समस्या यह है कि कभी कभी तीर कुंजी अब और उत्तरदायी नहीं हैं।

  • अगर मैं नियंत्रण संशोधक के साथ एक तीर कुंजी दबाता हूं तो कीडाउन ईवेंट निकाल दिया जाता है।

क्या आपको पता है कि मेरी तीर कुंजी अचानक फायरिंग घटना क्यों बंद कर देती है? एक नियंत्रण वर्ग से

निकाले जाते हैं और आप ProcessCmdKey विधि ओवरराइड कर सकते हैं:

+0

आप कोड है कि आप अपने KeyDown ईवेंट हैंडलर में मिल गया है पोस्ट कर सकते हैं। – ChrisF

+0

हां, कृपया करें। –

+0

हो सकता है कि यह आप में मदद मिलेगी? http://stackoverflow.com/questions/902767/c-tetris-clone-cant-get-block-to-respond-properly-to-arrow-key-combinations –

उत्तर

53
protected override bool IsInputKey(Keys keyData) 
    { 
     switch (keyData) 
     { 
      case Keys.Right: 
      case Keys.Left: 
      case Keys.Up: 
      case Keys.Down: 
       return true; 
      case Keys.Shift | Keys.Right: 
      case Keys.Shift | Keys.Left: 
      case Keys.Shift | Keys.Up: 
      case Keys.Shift | Keys.Down: 
       return true; 
     } 
     return base.IsInputKey(keyData); 
    } 
    protected override void OnKeyDown(KeyEventArgs e) 
    { 
     base.OnKeyDown(e); 
     switch (e.KeyCode) 
     { 
      case Keys.Left: 
      case Keys.Right: 
      case Keys.Up: 
      case Keys.Down: 
       if (e.Shift) 
       { 

       } 
       else 
       { 
       } 
       break;     
     } 
    } 
+1

ध्यान दें कि सभी टैब नियंत्रण के लिए रुकते हैं, झूठ होना चाहिए। (मुझे ऐसी समस्या का सामना करना पड़ा: डी) – Iman

+1

यह वास्तव में एक हैक है। सही जवाब के लिए Rodolfo Neuber उत्तर की जांच करें। – Ghigo

15

सर्वश्रेष्ठ उत्तर


(मेरे मूल जवाब) के लिए Rodolfo Neuber's reply देखें। माइक्रोसॉफ्ट ने KeyDown घटनाओं से इन चाबियों को छोड़ना चुना क्योंकि वे कई नियंत्रणों को प्रभावित करते हैं और फोकस को स्थानांतरित करते हैं, लेकिन इससे किसी भी अन्य तरीके से ऐप को इन कुंजीों पर प्रतिक्रिया करना मुश्किल हो जाता है।

+0

ऐसा लगता है कि ProcessCmdKey कीबोर्ड को सही तरीके से संभालने का एकमात्र तरीका है। धन्यवाद! –

+4

इस उत्तर मृत गलत है। अगर मैंने पहले से ही कुछ आधार नियंत्रण से ऑनकेडडाउन को ओवरराइड नहीं किया था जो पहले ही तीर कुंजियों (व्यवहार को बदलने के लिए) को संभाला था, तो मैं इसे नहीं जानता और इसे कठिन तरीके से लागू नहीं किया। नीचे अल्फा का जवाब देखें। – Joshua

+1

यहां तक ​​कि अल्फा के जवाब मेरी स्थिति के लिए काम नहीं करता है, लेकिन Snarfblam के does.Thank आप! – zionpi

2

दुर्भाग्यवश, KeyDown घटनाओं में प्रतिबंधों के कारण, तीर कुंजियों के साथ इसे पूरा करना काफी मुश्किल है।

  • रूप @Snarfblam कहा गया है, आप ProcessCmdKey विधि, जो तीर कुंजी दबाव पार्स करने की क्षमता को बरकरार रखे हुए ओवरराइड कर सकते हैं: हालांकि, इस के आसपास पाने के लिए कुछ तरीके हैं।
  • the accepted answer from this question राज्यों के रूप में, एक्सएनए में एक अंतर्निहित विधि है जिसे कीबोर्ड कहा जाता है। गेटस्टेट(), जो आपको तीर कुंजी इनपुट का उपयोग करने की अनुमति देता है। हालांकि, WinForms में यह नहीं है, लेकिन इसे पी/Invoke, या using a class that helps with it द्वारा किया जा सकता है।

मैं उस वर्ग का उपयोग करने की कोशिश करने की सलाह देता हूं। आप KeyDown घटना के साथ संयोजन में इस का उपयोग करते हैं, तो मुझे लगता है कि आप मज़बूती से अपने लक्ष्य को पूरा कर सकते हैं

var left = KeyboardInfo.GetKeyState(Keys.Left); 
var right = KeyboardInfo.GetKeyState(Keys.Right); 
var up = KeyboardInfo.GetKeyState(Keys.Up); 
var down = KeyboardInfo.GetKeyState(Keys.Down); 

if (left.IsPressed) 
{ 
//do something... 
} 

//etc... 

: यह काफी ऐसा करने के लिए आसान है।

42

मुझे एक ही समस्या थी। मैंने उत्तर @Snarfblam उत्तर दिया; हालांकि, यदि आप एमएसडीएन पर प्रलेखन पढ़ते हैं, तो ProcessCMDKey विधि किसी अनुप्रयोग में मेनू आइटम्स के लिए प्रमुख ईवेंट ओवरराइड करने के लिए है।

मैंने हाल ही में माइक्रोसॉफ्ट से इस आलेख में ठोकर खाई, जो काफी आशाजनक दिखता है: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.previewkeydown.aspx। माइक्रोसॉफ्ट के मुताबिक, तीर कुंजियों का पता लगाने के बाद PreviewKeyDown घटना में e.IsInputKey=true; सेट करने की सबसे अच्छी बात है।ऐसा करने से KeyDown ईवेंट को सक्रिय होगा।

यह मेरे लिए काफी अच्छा काम करता है और ProcessCMDKey को ओवरराइड करने से कम हैक-आईश था।

+0

बहुत अच्छा! यह मेरे लिए काम किया! – Pedro77

+0

यह चुने गए जवाब होना चाहिए, जिस तरह से क्लीनर है और यह अद्भुत काम करता है। – AStackOverflowUser

+0

हाँ यह काम करता है! जवाब काफी स्पष्ट है, लेकिन मैं यह निर्दिष्ट करना चाहता हूं कि 'IsInputKey'' e' वर्ग में है: 'e.IsInputKey = true'। – T30

14

मैं PreviewKeyDown

private void _calendar_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e){ 
     switch (e.KeyCode){ 
      case Keys.Down: 
      case Keys.Right: 
       //action 
       break; 
      case Keys.Up: 
      case Keys.Left: 
       //action 
       break; 
     } 
    } 
+1

मेरे लिए खूबसूरती से काम किया, – badbadboy

+0

उत्तराधिकारी/ओवरराइड करने की कोई आवश्यकता नहीं है, धन्यवाद। वास्तव में व्यवहार करता है जैसे कि मैं एक महत्वपूर्ण घटना का व्यवहार करने की अपेक्षा करता हूं। –

+1

उत्तर स्वीकार किया जाना चाहिए। – primo

0

उपयोग कर रहा हूँ के लिए एक प्रपत्र नियंत्रण में कीस्ट्रोक्स पर कब्जा करने के लिए, आप एक नया वर्ग है कि नियंत्रण जो आप चाहते के वर्ग पर आधारित है प्राप्त करना चाहिए, और आप ProcessCmdKey ओवरराइड()।

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 
{ 
    //handle your keys here 
} 

उदाहरण:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 
{ 
    //capture up arrow key 
    if (keyData == Keys.Up) 
    { 
     MessageBox.Show("You pressed Up arrow key"); 
     return true; 
    } 

    return base.ProcessCmdKey(ref msg, keyData); 
} 

पूर्ण स्रोत ... Arrow keys in C#

Vayne

0

करने के लिए सबसे अच्छा तरीका है, मुझे लगता है, इसे संभाल करने के लिए MSDN तरह को कहा है http://msdn.microsoft.com/en-us/library/system.windows.forms.control.previewkeydown.aspx

लेकिन इसे संभालें, आप कैसे हैं ईली की जरूरत है। मेरे रास्ते (नीचे उदाहरण में) हर KeyDown ;-)

/// <summary> 
    /// onPreviewKeyDown 
    /// </summary> 
    /// <param name="e"></param> 
    protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e) 
    { 
     e.IsInputKey = true; 
    } 

    /// <summary> 
    /// onKeyDown 
    /// </summary> 
    /// <param name="e"></param> 
    protected override void OnKeyDown(KeyEventArgs e) 
    { 
     Input.SetFlag(e.KeyCode); 
     e.Handled = true; 
    } 

    /// <summary> 
    /// onKeyUp 
    /// </summary> 
    /// <param name="e"></param> 
    protected override void OnKeyUp(KeyEventArgs e) 
    { 
     Input.RemoveFlag(e.KeyCode); 
     e.Handled = true; 
    } 
2

मैं जब WinForms से बाहर WPF खिड़की बुला ने वही समस्या थी पकड़ने के लिए है।

var wpfwindow = new ScreenBoardWPF.IzbiraProjekti(); 
    ElementHost.EnableModelessKeyboardInterop(wpfwindow); 
    wpfwindow.Show(); 

हालांकि, एक संवाद के रूप में खिड़की दिखा रहा है, यह

var wpfwindow = new ScreenBoardWPF.IzbiraProjekti(); 
    ElementHost.EnableModelessKeyboardInterop(wpfwindow); 
    wpfwindow.ShowDialog(); 

आशा इस मदद करता है काम किया।

0

मुझे एक ही समस्या थी और पहले से ही चयनित उत्तर में कोड का उपयोग कर रहा था। यह लिंक मेरे लिए जवाब था; शायद दूसरों के लिए भी।

How to disable navigation on WinForm with arrows in C#?

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