2010-11-16 18 views
7

मुझे एक गैर-दृश्य घटक, FooComponent बनाने की आवश्यकता है, जो Bar के सभी नियंत्रणों के लिए कुछ प्रबंधन करेगा जो इसके रूप में रहता है।.NET (गैर-दृश्य) घटक

  1. FooComponent केवल रूपों के लिए जोड़ा जा सकता है:

    मैं निम्नलिखित की कमी की है।

  2. केवल एक FooComponent प्रति फॉर्म की अनुमति है।
  3. FooComponent फॉर्म क्लोजिंग इवेंट में पंजीकरण करना चाहिए, और जब यह Bar के सभी पर आग लगती है और कुछ फ़ंक्शन पर लौटाई जाती है और लौटाए गए मानों के आधार पर e.Cancel मान भेजती है।

# 134 और # 2 उपरोक्त रन-टाइम के साथ ही डिजाइन समय पर लागू किया जाना चाहिए। # 3 ईवेंट पंजीकरण स्वचालित रूप से FooComponent के उपयोगकर्ताओं द्वारा किया जाना चाहिए।

मैंने कुछ मदद के लिए Google और MSDN की खोज की और लगभग Component और ComponentDesigner कक्षाओं को पढ़ा, लेकिन मुझे बचाव के लिए कुछ भी नहीं मिला।

मुझे क्या करना चाहिए?

+0

मुझे लगता है कि आप CodeDomSerializer (http://msdn.microsoft.com/en-us/library/system.componentmodel.design.serialization.codedomserializer.aspx) देख सकते हैं। यह तुम्हारा सबसे अच्छा शर्त हो सकता है। – PHeiberg

+0

@PHeiberg: धन्यवाद –

उत्तर

3

(1) यह नियंत्रित करने के लिए कि घटक को केवल एक फॉर्म में जोड़ा जा सकता है, FooComponent कन्स्ट्रक्टर का उपयोग करें जो एक फॉर्म पास हो गया है, और डिफ़ॉल्ट कन्स्ट्रक्टर को परिभाषित नहीं करता है। इसे इस तरह कहा जाता है:

FooComponent component = new FooComponent(this); 

जहां घटक स्वयं फॉर्म के भीतर से बनाया गया है। डिफ़ॉल्ट कन्स्ट्रक्टर को परिभाषित नहीं करके, यह:

FooComponent component = new FooComponent(); 

संकलित नहीं होगा।


(2) प्रपत्र पर ही एक FooComponent संपत्ति पर्दाफाश, और FooComponent के निर्माता में, सेट पारित कर दिया प्रपत्र के FooComponentthis करने के लिए।


(3) यही बात, FooComponent के लिए निर्माता में, प्रपत्र आप

पारित कर दिया के लिए समापन समारोह के साथ रजिस्टर


यह सब एक साथ रखो और आपको मिलता है:

public class MyForm : Form { 
    public FooComponent OwnedComponent { get; set; } 
} 


public class FooComponent { 

    public FooComponent (MyForm OwnerForm) { 
     OwnerForm.OwnedComponent = this; 
     OwnerForm.FormClosing += MyCallback; 
    } 

    private void MyCallback(object sender, FormClosingEventArgs e) { 
     ... 
    } 

} 



EDIT
दुर्भाग्यवश, यदि आपको वांछित है ई डिफ़ॉल्ट कन्स्ट्रक्टर, और यदि इसे एक वास्तविक ड्रॉप-ऑन-द-फॉर्म घटक होना है, तो यह लागू करने का कोई तरीका नहीं है कि एक घटक केवल एक फॉर्म पर बनाया गया है, या फ़ॉर्म में केवल घटक का एक उदाहरण है (से नहीं घटक के भीतर, वैसे भी)।

समस्या दोहरा है:
(1) एक घटक फार्म के लिए घटक शामिल नहीं करता गिराने, यह प्रपत्र के components संग्रह करने के लिए कहते हैं। तो अगर आप माता-पिता/मालिक को हैंडल प्राप्त कर सकते हैं, तो यह कभी भी एक फॉर्म नहीं होगा।

(2) जैसा कि नील ने इंगित किया है, एक फॉर्म पर एक घटक छोड़ना डिफ़ॉल्ट कन्स्ट्रक्टर को कॉल करता है, जो कोई पैरामीटर नहीं पास करता है, और, ज़ाहिर है, घटक के गुणों (जैसे साइट या कंटेनर) में से कोई भी पॉप्युलेट नहीं होता है।


संभवतः सहायक: एक घटक जब यह कई तरीकों से में बन जाता है अधिसूचित करने के लिए डिज़ाइन किया जा सकता है:

(1) एक निर्माता है कि एक IContainer पैरामीटर लेता है को लागू करने से। जब घटक को किसी फॉर्म पर गिरा दिया जाता है, तो जेनरेट कोड इसके बजाय इस कन्स्ट्रक्टर को कॉल करेगा। हालांकि, यह केवल रनटाइम पर ही करेगा, डिजाइन समय नहीं। लेकिन कंटेनर फॉर्म के components संग्रह के लिए एक हैंडल होगा।

public FooComponent(IContainer container) {...} 

(2) ISupportInitialize लागू करके। जब घटक को किसी रूप पर गिरा दिया जाता है, तो जेनरेट कोड अतिरिक्त रूप से BeginInit() और EndInit() पर कॉल करेगा। EndInit() में, आप Site और Container जैसे गुणों तक पहुंच सकते हैं। दोबारा, आप इसे केवल रनटाइम पर प्राप्त करेंगे, डिज़ाइनटाइम नहीं, और यहां अपवाद फेंकने से घटक को बनाए जाने से नहीं रोका जाएगा।

पुराने, लेकिन MSDN Magazine से माइकल वेनहार्ड और क्रिस सेल द्वारा घटक और नियंत्रण पर उत्कृष्ट लेख।
April 2003 Building Windows Forms Controls and Components with Rich Design-Time Features
May 2003 Building Windows Forms Controls and Components with Rich Design-Time Features, Part 2

ये अब .chm मदद फ़ाइलें हैं। डाउनलोड करने के बाद सामग्री को पढ़ने में सक्षम होने के लिए आपको फ़ाइल के प्रॉपर्टी पेज में अनब्लॉक करना होगा।

+0

खाली कन्स्ट्रक्टर की अनुमति न देने वाला नकारात्मक पक्ष यह है कि आप डिज़ाइन समय में नियंत्रण का उपयोग करने में सक्षम नहीं होंगे। –

+0

ओपी का कहना है कि यह एक गैर-दृश्य घटक है जो वह बना रहा है, इसलिए यह कोई समस्या नहीं होनी चाहिए। मेरा मतलब है कन्स्ट्रक्टर फूकंपोनेंट कन्स्ट्रक्टर है ... मैं स्पष्ट करता हूं कि –

+0

प्रश्न में मैं देखता हूं कि आपका क्या मतलब है ... यदि उसका शाब्दिक अर्थ है 'घटक' वह फॉर्म को खींच और छोड़ना चाहता है, तो आप ठीक है, उसके पास एक डिफ़ॉल्ट कन्स्ट्रक्टर होना चाहिए। –

1

मुझे नहीं लगता कि यह परिभाषित करना संभव है कि एक निहित वर्ग वास्तव में क्या हो सकता है। मैंने निश्चित रूप से कभी ऐसा उदाहरण नहीं देखा है जहां मुझे WinForms में एक प्रकार की एक संपत्ति की स्थापना करने के लिए एक त्रुटि (या यहां तक ​​कि एक चेतावनी) मिली है।

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

+0

मुझे डिज़ाइन समय में समर्थित होने की आवश्यकता है, क्या आप डिजाइन समय में # 3 प्राप्त करने के लिए किसी भी तरह से जानते हैं? –

1

आप बहुत कुछ पूछ रहे हैं। आम तौर पर, उन घटकों के बारे में जागरूक घटक बनाते हैं जिन्हें वे छोड़ दिया जाता है, काफी मुश्किल है। This answer इवेंट हैंडलर लागू करने में आपकी सहायता कर सकता है। ईवेंट हैंडलर को सेट करने के लिए EndInit() कॉल प्राप्त करने के लिए आपको ISupportInitialize को लागू करने की आवश्यकता होगी।

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

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