यह प्रश्न उन लोगों के लिए स्पष्ट प्रतीत होगा जो स्वयं समस्या का सामना नहीं कर चुके हैं।वर्चुअल ट्री व्यू: सही ढंग से हैंडलिंग चयन परिवर्तन
मुझे वीटीवी में चयन परिवर्तनों को संभालने की आवश्यकता है। मेरे पास नोड्स की एक फ्लैट सूची है। मुझे वर्तमान में चयनित सभी नोड्स के साथ सामान करने की आवश्यकता है जब भी
- उपयोगकर्ता नोड पर क्लिक करता है;
- उपयोगकर्ता शिफ्ट/Ctrl-node को नोड करता है;
- उपयोगकर्ता सूची को नेविगेट करने के लिए तीर कुंजियों का उपयोग करता है;
- उपयोगकर्ता खाली जगह या केवल चयनित नोड
आदि यह सबसे आम और अपेक्षित व्यवहार, बस Windows Explorer की तरह है Ctrl-क्लिक करने पर क्लिक करके माउस
मेरे कुछ शोध निम्नानुसार हैं।
पहले मैंने ऑनचेंज का उपयोग किया था। यह अच्छी तरह से काम करने के लिए लग रहा था, लेकिन मैं कुछ अजीब अस्थिर देखा और मैंने पाया है कि सबसे आम परिदृश्य में (एक नोड चयन किया जाता है, तो उपयोगकर्ता एक और एक पर क्लिक करना) OnChange दो बार निकाल दिया जाता है:
- जब वर्ष नोड सही का निशान हटाने । इस समय चयन खाली है। मैं सभी गुणों के स्थान पर "कुछ भी नहीं चुना गया" लेबल दिखाने के लिए अपने जीयूआई को रीफ्रेश करता हूं।
- जब नया नोड चुना जाता है। मैं नए नोड के गुण दिखाने के लिए फिर से अपना जीयूआई रीफ्रेश करता हूं। इसलिए झटकेदार।
यह समस्या googleable थी, इसलिए मैंने पाया कि लोग OnChange के बजाय OnFocusChange और OnFocusChanging का उपयोग करते हैं। लेकिन इस तरह से केवल एक चयन के लिए काम करता है। एकाधिक चयन के साथ, ड्रैग-चयन और नेविगेशन कुंजी यह काम नहीं करती है। कुछ मामलों में फोकस घटनाएं बिल्कुल भी आग लगती नहीं हैं (उदाहरण के लिए जब रिक्त स्थान पर क्लिक करके चयन हटा दिया जाता है)।
मैंने कुछ परिदृश्यों में इन हैंडलरों को कैसे निकाल दिया है, यह जानने के लिए मैंने कुछ डीबग आउटपुट अध्ययन किया था। जो मैंने पाया वह बिना किसी दृश्य या पैटर्न के कुल गड़बड़ है।
C OnChange
FC OnFocusChange
FCg OnFocusChanging
- nil parameter
* non-nil parameter
! valid selection
Nodes User action Handlers fired (in order)
selected
0 Click node FCg-* C*!
1 Click same FCg**
1 Click another C- FCg** C*! FC*
1 Ctlr + Click same FCg** C*!
1 Ctrl + Click another FCg** C*! FC*
1 Shift + Click same FCg** C*!
1 Shift + Click another FCg** C-! FC*
N Click focused selected C-! FCg**
N Click unfocused selected C-! FCg** FC*
N Click unselected C- FCg** C*! FC*
N Ctrl + Click unselected FCg** C*! FC*
N Ctrl + Click focused FCg** C*!
N Shift + Click unselected FCg** C-! FC*
N Shift + Click focused FCg** C-!
1 Arrow FCg** FC* C- C*!
1 Shift + Arrow FCg** FC* C*!
N Arrow FCg** FC* C- C*!
N Shift + Arrow (less) C*! FCg** FC*
N Shift + Arrow (more) FCg** FC* C*!
Any Ctrl/Shift + Drag (more) C*! C-!
0 Click empty -
1/N Click Empty C-!
N Ctrl/Shift + Drag (less) C-!
1 Ctrl/Shift + Drag (less) C-!
0 Arrow FCg** FC* C*!
यह पढ़ने में काफी मुश्किल है। संक्षेप में यह कहता है कि विशिष्ट उपयोगकर्ता कार्रवाई के आधार पर, तीन हैंडलर (ऑनचेंज, ऑनफोकस चेंज और ऑनफोकस चेंजिंग) को यादृच्छिक पैरामीटर के साथ यादृच्छिक क्रम में बुलाया जाता है। एफसी और एफसीजी कभी-कभी कभी नहीं बुलाया जाता है जब मुझे अभी भी ईवेंट की आवश्यकता होती है, इसलिए यह स्पष्ट है कि मुझे ऑनचेंज का उपयोग करना होगा।
लेकिन अगला कार्य यह है: ऑनचेंज के अंदर मुझे नहीं पता कि मुझे इस कॉल का उपयोग करना चाहिए या अगले के लिए इंतजार करना चाहिए। कभी-कभी चयनित नोड्स का सेट मध्यवर्ती और गैर-उपयोगी होता है, और इसे प्रोसेस करने से जीयूआई झिलमिलाहट और/या अवांछित भारी गणना होगी।
मुझे केवल उन कॉलों की आवश्यकता है जो "!" के साथ चिह्नित हैं उपरोक्त तालिका में। लेकिन उन्हें अंदर से अलग करने का कोई तरीका नहीं है। उदाहरण: यदि मैं "सी-" (ऑनचेंज, नोड = शून्य, चयनित गणना = 0) में हूं तो इसका अर्थ यह हो सकता है कि उपयोगकर्ता ने चयन हटा दिया (फिर मुझे इसे संभालने की आवश्यकता है) या उन्होंने एक और नोड क्लिक किया (फिर मुझे प्रतीक्षा करने की आवश्यकता है जब नया चयन बनता है तो अगला OnChange कॉल)।
वैसे भी, मुझे आशा है कि मेरा शोध अनावश्यक था। मुझे आशा है कि मुझे ऐसा कुछ याद आ रहा है जो समाधान को सरल और स्पष्ट कर देगा, और आप, लोग, मेरे लिए इसे इंगित करने जा रहे हैं। मेरे पास जो कुछ भी है, उसका उपयोग करके इस पहेली को हल करना कुछ बेहद अविश्वसनीय और जटिल तर्क उत्पन्न करेगा।
अग्रिम धन्यवाद!
धन्यवाद, @Tondrej! मैंने पहले कभी इस संपत्ति को नहीं देखा। और मैं ईमानदार होने के लिए ऐसी चीज मौजूद होने की उम्मीद नहीं करूंगा। लेकिन यह मेरी समस्या को हल करने का 'आधिकारिक' तरीका प्रतीत होता है। मैंने कोशिश की और यह काम करता है, लेकिन थोड़ा अजीब लगता है ... टाइमर के साथ ऐसी समस्याओं को हल करना मेरे लिए वास्तव में एक बुरा विचार है। लेकिन अगर समय के साथ कोई बेहतर समाधान नहीं आता है, तो मुझे इसे चिपकना होगा। – 13x666
@ 13x666 यदि आप इसके बारे में सोचते हैं, तो इस मामले में झिलमिलाहट से बचने का मतलब है कि यदि वे चीजों (उपयोगकर्ता इनपुट) "शांत हो जाएं" के बाद एक का पालन करते हैं तो स्क्रीन अपडेट को दबाकर इसका मतलब है। –
+1। @ 13x666, एक टाइमर वास्तव में एक * बहुत * हल्का वजन समाधान है जो उपयोगकर्ता इनपुट को "शांत" करने की प्रतीक्षा करता है, क्योंकि टोंड्रेज इसे रखता है। यह अनिवार्य रूप से SetTimer API पर एक कॉल है। मैंने सफलतापूर्वक ग्रेट सफलता के साथ कई बार इस उद्देश्य के लिए टाइमर का उपयोग किया है।उपयोगकर्ता उप-200-एमएस देरी को नोटिस नहीं करेगा, लेकिन उपयोगकर्ता जीयूआई को अनावश्यक रूप से चित्रित करने के कारण बाद के आदेशों को संसाधित करने में झिलमिलाहट और देरी नोटिस करेगा। –