2008-10-02 15 views
10

क्या मुख्य फ़ॉर्म उपयोगकर्ता नियंत्रण पर उप-नियंत्रण पर घटनाओं को फायर करने में सक्षम होने का कोई तरीका है?मैं WinForms ऐप में उपयोगकर्ता-नियंत्रण पर उप-नियंत्रण से ईवेंट कैसे प्राप्त करूं?

मेरे पास मेरे आवेदन के मुख्य रूप में एम्बेडेड एक कस्टम उपयोगकर्ता नियंत्रण है। नियंत्रण में विभिन्न उप-नियंत्रण होते हैं जो डेटा में हेरफेर करते हैं, जो मुख्य रूप से अन्य रूपों द्वारा अन्य नियंत्रणों द्वारा प्रदर्शित होता है। मुझे क्या चाहिए यदि उपयोगकर्ता को किसी भी तरह से सूचित किया जा सकता है जब उपयोगकर्ता subcontrols बदलता है, तो मैं डेटा और संबंधित डिस्प्ले कहीं और अपडेट कर सकता हूं।

अभी, मैं धोखा दे रहा हूं। मेरे पास उप-नियंत्रकों की फोकस-छोड़ने वाली घटना के लिए एक प्रतिनिधि है। यह प्रतिनिधि उपयोगकर्ता-नियंत्रण की एक संपत्ति को बदलता है जिसे मैं कहीं और नहीं उपयोग कर रहा हूं (इस कारण, कारणों को वैधता)। उसके बाद मेरे पास मुख्य रूप से परिभाषित एक प्रतिनिधि होता है जब उपयोगकर्ता नियंत्रण की कारणों की वैधता संपत्ति बदलती है, जो तब ऐप को डेटा और प्रदर्शन को अपडेट करने के लिए निर्देशित करती है।

एक समस्या उत्पन्न होती है क्योंकि जब मेरे पास फोकस उपयोगकर्ता नियंत्रण को छोड़ देता है, तो मेरे पास एक प्रतिनिधि सेट अप भी होता है, क्योंकि उपयोगकर्ता को कुछ और करने की अनुमति देने से पहले मुझे उपयोगकर्ता-नियंत्रण में फ़ील्ड को सत्यापित करने की आवश्यकता होती है। हालांकि, यदि उपयोगकर्ता बस उप-नियंत्रण के बीच स्विच कर रहा है, तो मैं मान्य नहीं करना चाहता, क्योंकि वे संपादन नहीं कर सकते हैं।

असल में, मैं डेटा को अद्यतन करना चाहता हूं जब उपयोगकर्ता उप-नियंत्रण स्विच करता है या उपयोगकर्ता नियंत्रण छोड़ देता है, लेकिन मान्य नहीं करता है। जब उपयोगकर्ता नियंत्रण छोड़ देता है, तो मैं अपडेट करना और मान्य करना चाहता हूं। अभी, उपयोगकर्ता नियंत्रण को छोड़कर दो बार आग लगने का सत्यापन होता है।

+0

नियंत्रण की विभिन्न घटनाओं के मुख्य स्वरूप को जोड़ने में क्या गलत है? घटनाओं का एक टन है जो अधिकांश विनफॉर्म नियंत्रणों के लिए आग – Sekhat

+0

मुझे लगता है कि मैं समझ नहीं पा रहा हूं कि आप क्या हासिल करना चाहते हैं: पी – Sekhat

+0

डिजाइनर के माध्यम से पहले प्रश्न का उत्तर देने के लिए (जो मैं अपेक्षाकृत नया हूं, मेरे जीयूआई संपादन के लिए उपयोग कर रहा था), मेरे फॉर्म में केवल उपयोगकर्ता नियंत्रण द्वारा उठाए गए कार्यक्रमों तक पहुंच है, न कि इसके उप-नियंत्रण। मुझे याद रखने में असफल रहा कि मैं अपनी घटनाओं को आग लगा सकता हूं और उनको संभाल सकता हूं। –

उत्तर

15

सर्वोत्तम अभ्यास UserControl पर घटनाओं का पर्दाफाश करना होगा जो घटनाओं को मूल रूप से बुलबुला करते हैं। मैं आगे बढ़ गया हूं और आपके लिए एक उदाहरण रखता हूं। यहां यह उदाहरण दिया गया है कि यह उदाहरण क्या प्रदान करता है।

  • UserControl1
    • बनाएँ UserControlTextBox1 साथ
    • UserControlControlChanged
    • बुलाया UserControl के भीतर पर एक सार्वजनिक समारोह रजिस्टर TextBox1 TextChangedEvent के लिए रजिस्टर एक ईवेंट हैंडलर
    • TextChangeEvent हैंडलर के भीतर फ़ंक्शन मैंपर कॉल करता हूं माता-पिता प्रपत्र
  • Form1
    • ड्रॉप डिजाइनर
    • MouseLeave के लिए UserControl1 पर एक ईवेंट हैंडलर रजिस्टर और ControlChanged
के लिए पर UserControl1 का एक उदाहरण के लिए बुलबुले के 03,210 घटना

यहां एक स्क्रीनशॉट दिखाया गया है जिसमें ControlChanged ईवेंट जिसे मैंने UserControl पर परिभाषित किया है, मूल विंडोज़ फॉर्म पर विजुअल स्टूडियो में यूएक्स के माध्यम से उपलब्ध है।

Event Handlers for User Control http://friendfeed.s3.amazonaws.com/0d5a3968cb785625c8afb3974a8d84894c476291

+0

धन्यवाद, माउसलवेव के बजाय, मैं वही कर रहा हूं, मैंने फ़ोकसलेव का उपयोग किया, क्योंकि हर बार जब उपयोगकर्ता अपना माउस चलाता है तो परेशान हो सकता है। इसके अलावा, इसके लिए सभी कामों के माध्यम से जाने के लिए धन्यवाद! –

+0

इसलिए यदि आपके पास बहुत से अलग नियंत्रण हैं (मान लें, एक टेक्स्टबॉक्स, एक बटन, एक चेकबॉक्स और एक लेबल), और यह कि उन सभी नियंत्रणों के उचित/वास्तविक घटनाओं को उपयोगकर्ता नियंत्रण (स्वयं निहित उपयोगकर्ता नियंत्रण) के अंदर संभाला जाता है, और आप कंटेनर फॉर्म में एक एकल ईवेंट (कहें, MyControl.OnClick) को बबल करना चाहते थे, क्या आप एक ही विधि/तंत्र के माध्यम से एक ही विधि/तंत्र के माध्यम से सभी सबकंट्रोल ईवेंट को "हाइजैक" कर सकते हैं, या फिर भी आपको प्रत्येक subcontrol घटना मैन्युअल रूप से तार और प्रत्येक के लिए खुद को बुलबुला संभाल लें? – MaxOvrdrv

+1

लिंक काम नहीं करता है। कोड को उत्तर में टेक्स्ट के रूप में जाना चाहिए, ज़िप फ़ाइल डाउनलोड करने के लिंक के रूप में नहीं। – ardila

2

इस तरह की चीज़ के लिए सबसे अच्छा मॉडल आपके उपयोगकर्ता नियंत्रण पर कस्टम ईवेंट बनाएगा, और उचित समय पर उन्हें उठाएगा।

आपका परिदृश्य काफी जटिल है, लेकिन इसकी अनदेखी नहीं है। (मैं वास्तव में अपनी वर्तमान परियोजनाओं में से एक पर एक बहुत ही समान मोड में हूं।) जिस तरह से मैं इसका दृष्टिकोण करता हूं वह यह है कि उपयोगकर्ता नियंत्रण अपने सत्यापन के लिए ज़िम्मेदार है। मैं कारणों का उपयोग नहीं करता; इसके बजाय उचित उपयोगकर्ता नियंत्रण बिंदु पर, मैं ValidateChildren() के ओवरराइड के माध्यम से सत्यापन करता हूं। (आमतौर पर ऐसा होता है जब उपयोगकर्ता उपयोगकर्ता नियंत्रण पर "सहेजें" या "अगला" क्लिक करता है।)

आपके उपयोगकर्ता नियंत्रण UI से परिचित नहीं है, जो आपके लिए 100% सही दृष्टिकोण नहीं हो सकता है। हालांकि, यदि आप कस्टम इवेंट बढ़ाते हैं (संभवतः कस्टम इवेंटआर्ज़ के साथ जो निर्दिष्ट करता है कि सत्यापन करने के लिए या नहीं), तो आप यह कहां प्राप्त कर सकते हैं कि आप कहां बनना चाहते हैं।

2

उपयोगकर्ता नियंत्रण पर ही कुछ कस्टम घटना गुण के माध्यम से उन्हें प्रकाशित आप घटनाओं को अपने उपयोगकर्ता नियंत्रण के अंदर कब्जा करने के बारे में परवाह ऊपर तार की जरूरत है, और। एक साधारण उदाहरण के लिए एक बटन क्लिक करें घटना लपेटकर किया जाएगा:

// CustomControl.cs 
// Assumes a Button 'myButton' has been added through the designer 

// we need a delegate definition to type our event 
public delegate void ButtonClickHandler(object sender, EventArgs e); 

// declare the public event that other classes can subscribe to 
public event ButtonClickHandler ButtonClickEvent; 

// wire up the internal button click event to trigger our custom event 
this.myButton.Click += new System.EventHandler(this.myButton_Click); 
public void myButton_Click(object sender, EventArgs e) 
{ 
    if (ButtonClickEvent != null) 
    { 
    ButtonClickEvent(sender, e); 
    } 
} 

फिर, प्रपत्र नियंत्रण है कि का उपयोग करता है, तो आप आप की तरह घटना ऊपर तार किसी अन्य होगा:

// CustomForm.cs 
// Assumes a CustomControl 'myCustomControl' has been added through the desinger 
this.myCustomControl.ButtonClickEvent += new System.EventHandler(this.myCustomControl_ButtonClickEvent); 
myCustomControl_ButtonClickEvent(object sender, EventArgs e) 
{ 
    // do something with the newly bubbled event 
} 
+0

शायद मैं गलत हूं या मैं वास्तव में विचार को समझ नहीं पा रहा हूं, लेकिन वहां ' 'MyFroject.CustomControl.ButtonClickHandler()' 'NewF System.EventHandler()' 'CustomForm.cs' में '? – MRM

0

मैं चाहते हैं जैसा कि वर्णन किया गया है, इसमें वास्तव में लगता है, यह वास्तव में लगता है जैसे आप एक लाल हेरिंग का पीछा कर रहे हैं। हालांकि ऐसा लगता है कि आपके पास ऐसी स्थिति है जहां WinForms में बुलबुले की घटना की कमी आपको परेशानी का कारण बन रही है, वास्तविकता यह है कि एक खराब वास्तुकला आपको घटनाओं पर बुलबुले की आवश्यकता में मजबूर कर रही है जब आपको नहीं करना चाहिए।

यदि आप अपने डिज़ाइन को रीफैक्टर/पुनर्गठन कर सकते हैं जैसे कि नियंत्रण एक सामान्य डेटा मॉडल (एमवीसी/एमवीपी स्पष्ट विकल्प हैं) के साथ काम कर रहे हैं तो आप अपने मुख्य फॉर्म को बताने के लिए मॉडल पर प्रॉपर्टी चेंज किए गए ईवेंट जैसे सामान्य WinForms पैटर्न को लागू कर सकते हैं। और कोई भी अन्य नियंत्रण जो डेटा को स्वयं अपडेट करने के लिए उपभोग करता है।

संक्षेप में, अन्य उत्तरों उचित हैं कि वे पूछे गए प्रश्न का उत्तर देते हैं। लेकिन एक कोड गुणवत्ता दृष्टिकोण से, मुझे लगता है कि बेहतर जवाब यूआई से अपने डेटा को अलग करना है।

1

यदि कोई अभी भी सोच रहा है कि WinForm में ईवेंट बबलिंग को अनुकरण कैसे करें, तो Application.AddMessageFilter देखने के लिए एक अच्छी जगह है।

इस विधि का उपयोग करके आप अपने स्वयं के फ़िल्टर को इंस्टॉल कर सकते हैं जो को को मौजूदा थ्रेड के संदेश कतार में पोस्ट किया जा रहा है।

आपको अवगत होना चाहिए कि भेजे गए संदेश (पोस्ट नहीं किए गए) को इस फ़िल्टर द्वारा नियंत्रित नहीं किया जा सकता है।चारों ओर, सबसे दिलचस्प घटनाएं (जैसे क्लिक इवेंट) पोस्ट की जाती हैं और नहीं भेजी जाती हैं और इसलिए इस फ़िल्टर द्वारा निगरानी की जा सकती है

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