2012-08-25 7 views
7

मैंने Keyboard.Modifiers के उपयोग का सुझाव देने के लिए कई उत्तरों को देखा है, यह निर्धारित करने के लिए कि KeyDown ईवेंट एक कुंजी के लिए है जो एक संशोधक सेट था। दुर्भाग्यवश, क्योंकि Keyboard.Modifiersवर्तमान संशोधक की स्थिति (कुंजी दबाए जाने पर संशोधक की स्थिति के बजाय) लौटाता है, इसके परिणामस्वरूप त्वरित टाइपिस्ट के लिए वास्तव में कष्टप्रद अस्थायी बग होता है।WPF KeyDown ईवेंट में संशोधक कुंजी को सही ढंग से कैसे पुनर्प्राप्त करें?

विशेष रूप से, कल्पना करें कि कोई व्यक्ति Ctrl + A दबाता है, और ए दबाए जाने के बाद केवल कुछ मिलीसेकंड को रिलीज़ करता है। अब कल्पना करें कि सिस्टम भारी भार में था; कुंजी हैंडलर ने निष्पादन शुरू कर दिया लेकिन 50 एमएमएस के लिए छूट दी गई थी। जब तक कुंजी हैंडलर फिर से निष्पादित कर रहा है, वर्तमान Ctrl की स्थिति "जारी" है। कुंजी हैंडलर अब सोचेंगे कि "ए" को Ctrl के बिना दबाया गया था, और यह खराब है।

इसी प्रकार, यदि एक तेजी से टाइपिस्ट एक में प्रवेश करती है, Ctrl + End और अपने आवेदन Keyboard.Modifiers का उपयोग करता है, यह बजाय अवलोकन Ctrl + A लग सकती है ...

WinForms में, KeyDown घटना मुझे Ctrl के राज्य बताता है बिल्कुल, भले ही यह पहले से ही ईवेंट द्वारा संभाला जा रहा है, तब तक इसे रिलीज़ किया गया हो। मैं WPF में यह वही व्यवहार कैसे प्राप्त कर सकता हूं?

संपादित: ऐसा लगता है कि वास्तव में Keyboard.Modifiers "वर्तमान" संशोधक कुंजियों को पुनः प्राप्त नहीं है संभव है, लेकिन जैसा कि कुंजी दबाए संदेश अभी संसाधित किया जा करने के लिए संबंधित के बजाय संशोधक कुंजियों। WinAPI में, यह "async" और गैर-async कुंजी राज्य कार्यों के बीच भेद था। दुर्भाग्यवश, the documentation का उल्लेख नहीं है कि वास्तव में "वर्तमान" का अर्थ क्या है। अगर कोई जानता है, तो कृपया ऐसा कहें।

+0

क्या आप निश्चित हैं? मुझे msdn पर कोई संकेत नहीं मिला है, जो आपके सिद्धांत का प्रमाण देगा ... यह वास्तव में अजीब होगा कि हैंडलर-तर्कों में मूल रूप से दबाए गए कुंजी शामिल नहीं हैं ... यदि आप "ऑनकीडाउन" से जुड़ते हैं और उपयोगकर्ता नियंत्रण (पकड़) दबाता है और फिर ए, फिर नियंत्रण जारी करता है, घटना 2 बार निकाल दी जाएगी! "नियंत्रण" के साथ ही है, तो नियंत्रण + A ... साथ अजीब का एक छोटा सा पहले - imho, हम समझ सकते हैं कि आसानी से Thread.Sleep के साथ बाहर ... मैं बूट करने के लिए वी.एस. अप की क्या ज़रूरत है अभी? ;) – TheHe

+1

@TheHe हैंडलर तर्कों में मूल रूप से दबाए गए _key_ शामिल हैं, लेकिन संशोधक कुंजी जानकारी नहीं। अच्छे पुराने WinAPI में, संशोधक कुंजी संदेश के साथ पारित कर रहे हैं। WinForms में भी ऐसा ही होता है। दस्तावेज़ वास्तव में आपको चेतावनी देता है कि _current_ स्थिति को आजमाएं और संसाधित न करें; उदाहरण के लिए, यदि एप्लिकेशन किसी भी कारण (जैसे एचडीडी थ्रैशिंग) के लिए उत्तरदायी नहीं था, तो इस तथ्य के बाद हैंडलर को _seconds_ लगाया जा सकता है। –

उत्तर

3

जैसा कि घटना में कोई संशोधक जानकारी प्रतीत नहीं होती है, आप तर्क देते हैं कि आप कुछ क्षेत्रों में स्वयं को राज्य का ट्रैक रख सकते हैं और KeyUp और KeyDown दोनों को तदनुसार अपडेट कर सकते हैं।

उदा।

private bool ctrl = false; 
private void This_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.Key == Key.LeftCtrl) //or switch, also: `LeftCtrl` & `RightCtrl` are treated as separate keys 
     ctrl = true; 
    //etc.. 
} 

private void This_KeyUp(object sender, KeyEventArgs e) 
{ 
    if (e.Key == Key.LeftCtrl) 
     ctrl = false; 
    //etc.. 
} 

क्या यह वास्तव में एक अच्छा विचार मैं नहीं कह सकता है ...


आप कुंजी इशारों मैं KeyBindings तरह समर्पित तरीकों का उपयोग कर सुझाव है कि वे केवल सक्रिय किया जाना चाहिए जब इशारा हुआ संभालने के लिए चाहते हैं । अन्य इनपुट के लिए आप TextInput पर भी एक नज़र डालना चाहते हैं जो अधिक सार है और उस पाठ को लौटाता है जिस पर इनपुट का अनुवाद किया जाता है।

+0

कीबाइंडिंग के बारे में अच्छा बिंदु; इसकी जांच करेंगे। –

+0

मेरे डबल-उत्तर के लिए सूखी - मैं पूरी तरह से इसे खत्म कर देता हूं! – TheHe

2

इस विनाशकारी उत्तर के लिए खेद है, लेकिन ...

के बाद यह मेरे लिए स्पष्ट हो जाता है अनुसंधान का एक छोटा सा ... घटना "KeyDown" नहीं "KeyCombinationDown" कहा जाता है, तो यह किसी भी पूरी तरह से स्वतंत्र है संशोधक पहले दबाए गए ...

वास्तव में आपके लक्ष्य को प्राप्त करने का एक सही तरीका है: कमांडिंग-पैटर्न का उपयोग करना।

आप एक COMMAND परिभाषित करते हैं (WPF-Commanding के लिए Google देखें) और अपने एप्लिकेशन में एक कीबाइंडिंग जोड़ें, जहां आप कुंजी या कुंजी/कुंजी-संयोजन को परिभाषित करते हैं जो कमांड को आग लग जाएगा ... http://msdn.microsoft.com/en-us/library/system.windows.input.keybinding.aspx

IMHO, इस केवल रास्ता और अर्थ की दृष्टि से और अधिक सुरुचिपूर्ण, भी है:

उदाहरण देखें।

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

चीयर्स।

+0

मैं इसे विनाशकारी के रूप में नहीं देखता हूं। आप सब के बाद एक विकल्प का सुझाव देते हैं। यह सिर्फ इतना है कि यदि आप चारों ओर Google करते हैं, तो आप केवल "कीबोर्ड का उपयोग करें। मॉडिफायर्स" देखेंगे, इसलिए यह प्रश्न ... –

+0

दुर्भाग्यवश इसका दुष्प्रभाव है (बग?): जब कुंजी बाध्यकारी मिलान होते हैं, तो कुंजी डाउन इवेंट * हमेशा * संभाले जाने के रूप में चिह्नित, भले ही आदेश निष्पादित नहीं हो सकता है। तो उस स्थिति में कुंजी प्रेस का कभी भी टेक्स्ट इनपुट में अनुवाद नहीं किया जाएगा। –

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