2010-05-14 12 views
6

मुझे सी # .NET के तहत फ़ॉर्म की रूपरेखा के साथ समस्या है। मान लें कि मेरे पास मुख्य रूप # 0 है (नीचे दी गई छवि देखें)। यह फॉर्म मुख्य आवेदन पत्र का प्रतिनिधित्व करता है, जहां उपयोगकर्ता विभिन्न परिचालन कर सकता है। हालांकि, समय-समय पर अतिरिक्त कार्यों को समर्थन देने के लिए अतिरिक्त गैर-मोडल फॉर्म खोलने की आवश्यकता होती है। मान लें कि यह छवि में फॉर्म # 1 है। इस # 1 फॉर्म पर एक दूसरे के शीर्ष पर कुछ अतिरिक्त मोडल फॉर्म खोले जा सकते हैं (छवि में # 2 फॉर्म), और अंत में, एक प्रगति संवाद होता है जो एक लंबी ऑपरेशन प्रगति और स्थिति दिखाता है, जो कुछ से ले सकता है कुछ घंटों तक मिनट। समस्या यह है कि मुख्य रूप # 0 उत्तरदायी नहीं है जब तक कि आप सभी मोडल रूपों को बंद न करें (छवि में # 2)। मुझे इसकी आवश्यकता है कि मुख्य स्थिति # 0 इस स्थिति में परिचालित होगा। हालांकि, यदि आप फ़ॉर्म # 2 में एक गैर-मोडल फॉर्म खोलते हैं, तो आप दोनों मोडल # 2 फॉर्म और नव निर्मित गैर मोडल फॉर्म के साथ काम कर सकते हैं। मुझे मुख्य फॉर्म # 0 और फॉर्म # 1 के बीच अपने सभी बच्चों के रूपों के समान व्यवहार की आवश्यकता है। क्या यह संभव है? या मुझ से कुछ गलत हो रहा है? हो सकता है कि वहाँ वैकल्पिक हल के कुछ प्रकार है, मैं वास्तव में सभी ShowDialog दिखाएँ करने के लिए कॉल को बदलने के लिए नहीं करना चाहते हैं ...WinForms प्रोग्रामिंग - मॉडल और गैर-मोडल फॉर्म समस्या

Image http://img225.imageshack.us/img225/1075/modalnonmodalproblem.png

+2

क्या आप एक ऐसा फॉर्म बनाने के लिए कह रहे हैं जो आपके अन्य रूपों में से एक के लिए केवल मोडल है? – SLaks

+0

मैं चाहता हूं कि मुख्य रूप # 0 कुछ अतिरिक्त मोडल बाल रूपों (# 2) के साथ एक गैर मोडल फॉर्म # 1 खोले जाने पर उत्तरदायी रहेगा। – Povilas

उत्तर

12

मॉडल रूप वास्तव में "मोडल" का अर्थ है, वे ऐप में अन्य सभी विंडो अक्षम करते हैं। यह महत्वपूर्ण है, आपका कार्यक्रम कुछ हद तक खतरनाक राज्य में है। आपके पास कोड का एक हिस्सा है जो संवाद को बंद करने की प्रतीक्षा कर रहा है। वास्तव में खराब चीजें हो सकती हैं अगर उन अन्य विंडोज़ अक्षम नहीं हैं। जैसे उपयोगकर्ता फिर से मोडल डायलॉग शुरू कर सकता है, अब आपका कोड दो बार घोंसला है। या वह संवाद की मालिक विंडो बंद कर सकती है, अब यह अचानक गायब हो जाती है।

यदि आप एप्लिकेशन को कॉल करते हैं तो आप ठीक तरह की समस्याओं का सामना कर सकते हैं। DoEvents() एक लूप के अंदर। अन्य खिड़कियों को अक्षम किए बिना मोडल व्यवहार करने का एक तरीका प्राप्त करने का एक तरीका कौन सा है। उदाहरण के लिए:

Form2 mDialog; 

    private void button1_Click(object sender, EventArgs e) { 
     mDialog = new Form2(); 
     mDialog.FormClosed += (o, ea) => mDialog = null; 
     mDialog.Show(this); 
     while (mDialog != null) Application.DoEvents(); 
    } 

यह खतरनाक है।

मॉडल रूपों का उपयोग करना निश्चित रूप से सबसे अच्छा है जिस तरह से उन्हें परेशानी से बाहर रहने के लिए डिज़ाइन किया गया था। यदि आप एक मोडल फॉर्म नहीं चाहते हैं तो बस इसे मोडल न करें, शो() विधि का उपयोग करें। सदस्यता लें अपने FormClosing घटना के लिए पता करने के लिए इसके बारे में बंद करने के लिए है कि:

private void button1_Click(object sender, EventArgs e) { 
     var frm = new Form2(); 
     frm.FormClosing += new FormClosingEventHandler(frm_FormClosing); 
     frm.Show(); 
    } 

    void frm_FormClosing(object sender, FormClosingEventArgs e) { 
     var frm = sender as Form2; 
     // Do something with <frm> 
     //... 
    } 
+0

आपके उत्तर के लिए धन्यवाद, मुझे लगता है कि मैं एक अलग जीयूआई थ्रेड का उपयोग कर सकता हूं, क्योंकि मुख्य रूप # 0 और फॉर्म # 1 मूल रूप से अपने जीवन जीते हैं और एक दूसरे के साथ बातचीत नहीं करते हैं। फॉर्म # 1 भी एक अलग आवेदन हो सकता है। मैं शोडिअलॉग() को दिखाने के लिए नहीं बदल सकता() क्योंकि मुझे मोडल रूपों की आवश्यकता है लेकिन केवल फॉर्म # 1 संदर्भ में। उपयोगकर्ता फॉर्म # 1 के साथ काम नहीं कर सकता (केवल फॉर्म # 1 के साथ) जब तक फॉर्म # 1 से खोला गया मॉडल नहीं बंद हो जाता है। – Povilas

3

पहली बात यह है कि मन में आता है कुछ इस तरह होगा। जब आप फॉर्म 2 लॉन्च करते हैं तो आप फॉर्म 1 को अक्षम कर सकते हैं और उसके बाद फॉर्म 1 को दूसरे फॉर्म की बंद घटना को स्वयं को पुनः सक्षम करने के लिए संभाल सकता है। आप शो संवाद का उपयोग करके मोडल 2 नहीं खोलेंगे।

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

0

आपका मुख्य फॉर्म उत्तरदायी नहीं होगा जब तक कि एक ही प्रक्रिया स्थान में मौजूद किसी भी मोडल संवाद बंद न हों। इसके लिए काम नहीं है।

0

यह मेरे लिए लगता है कि आप एक एमडीआई आवेदन को सही पर पर्चा # 0 IsMdiContainer संपत्ति की स्थापना इस्तेमाल कर सकते हैं।

उसके बाद, आप कुछ एक जैसे कर सकता है:

public partial class Form0 { 
    public Form0 { 
     InitializeComponent(); 
     this.IsMdiContainer = true; // This will allow the Form #0 to be responsive while other forms are opened. 
    } 

    private void button1_Click(object sender, EventArgs e) { 
     Form1 newForm1 = new Form1(); 
     newForm1.Parent = this; 
     newForm1.Show(); 
    } 
} 

के रूप में आप अपने प्रश्न में कहा गया है रूपों Modal = true के सभी कर देगा ShowDialog() का उपयोग करना।

परिभाषा के अनुसार, एक मॉडल रूप है:

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

आप इस प्रॉपर्टी का उपयोग कर सकते हैं [(Modal)] यह निर्धारित करने के लिए कि किसी विधि या प्रॉपर्टी से प्राप्त एक फॉर्म को सामान्य रूप से प्रदर्शित किया गया है या नहीं।

तो, एक मॉडल फार्म केवल इस्तेमाल किया जाएगा जब आप उपयोगकर्ता से तत्काल सहायता/सहभागिता की आवश्यकता है। मोडल रूपों का उपयोग करना अन्यथा विश्वास करता है कि आप शायद गलत दिशा में चल रहे हैं।

यदि आप नहीं चाहते हैं कि आपका मुख्य रूप एमडीआई कंटेनर हो, तो शायद मल्टीथ्रेडिंग का उपयोग करना एक सरल BackgroundWorker कक्षा के माध्यम से एक समाधान है जो आप प्राप्त करना चाहते हैं। इस प्रकार, यह एक डिजाइन गंध की तरह मुझे लग रहा है ...

  • यह क्या, क्या करना चाहते हैं अपने मुख्य रूप उत्तरदायी बनाने का अलग, आदि
  • है आपको क्या करना है यह क्या है ?

आपको जो करना है, उसे समझाते हुए, हम आपको सही तरीके से, या कम से कम शायद बेहतर दिशा में मार्गदर्शन करने में सक्षम हो सकते हैं।

+0

आपके उत्तर के लिए धन्यवाद, मैं बेहतर व्याख्या करने की कोशिश करूंगा। एमडीआई या शोडिअलॉग() को दिखाने के लिए() को मेरे लिए हल नहीं किया जाएगा, क्योंकि मुझे मोडल फॉर्म (कस्टम डेटा एडिटर्स) की आवश्यकता है और उपयोगकर्ता आगे बढ़ने तक आगे नहीं बढ़ सकता है, लेकिन मुझे केवल काम करने के लिए सामान्यता की आवश्यकता है फॉर्म # 1 संदर्भ में। फॉर्म # 1 उपयोगकर्ता कुछ डेटा के साथ काम कर रहे हैं जिसे बाद में मुख्य रूप # 0 पर आवश्यक है। असल में, मुख्य रूप # 0 और फॉर्म # 1 अपने जीवन जीते हैं, और फॉर्म # 1 भी अलग एप्लिकेशन हो सकता है। # 0 से कुछ सिंगलटन ऑब्जेक्ट्स से डेटा ले रहा है, जहां फॉर्म # 1 डेटा अपडेट कर रहा है। – Povilas

+0

साल के आधे से सब कुछ ठीक था, लेकिन नई आवश्यकताओं के चलते मेरे पास ऐसी स्थिति है जहां एक कस्टम डेटा एडिटर के साथ काम करने में कुछ घंटे लग सकते हैं। इसलिए मुझे लगता है कि मैं हंस पासेंट का सुझाव दे सकता हूं - एक अलग जीयूआई थ्रेड। और कुछ सिंगलटन ऑब्जेक्ट्स के माध्यम से डेटा सिंक्रनाइज़ करें। – Povilas

-1

वास्तव में उत्तर बहुत आसान है।

newForm.showDialog(); 

यह एक नया रूप खुल जाएगा, जबकि माता-पिता एक पहुंच योग्य नहीं होगा।

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