2009-04-08 15 views
7

से एक फॉर्म बंद करना मेरे पास एक बहुत ही अजीब व्यवहार है जो केवल एक रूप में होता है।लोड हैंडलर

असल में मैं Form का उदाहरण बना रहा हूं, और फॉर्म को गैर-अवरुद्ध करने के लिए Show() पर कॉल कर रहा हूं। उस फॉर्म के Load इवेंट हैंडलर में, मेरे पास कुछ तर्क हैं जो कुछ परिस्थितियों में this.Close() पर कॉल कर सकते हैं। यह फॉर्म बंद कर देता है, लेकिन उसके बाद क्लाइंट कोड में Show() विधि ObjectDisposedException फेंकता है।

ObjectDisposedException से स्टैक ट्रेस इस प्रकार है:

System.Windows.Forms.Control.CreateHandle()
System.Windows.Forms.Form.CreateHandle पर() पर
प्रणाली पर .Windows.Forms.Control.get_Handle()
System.Windows.Forms.ContainerControl.FocusActiveControlInternal()
System.Windows.Forms.Form.SetVisibleCore पर (बूलियन वैल्यू)
System.Windows.Forms.Control पर पर .Show()
... आदि।

यह मैं क्या दिखाई दे रही है है होती हैं:

  1. Control.Show() कहा जाता है
  2. मेरी प्रपत्र शुरू की है
  3. OnFormLoad विधि, कहा जाता है के अंदर
  4. FormLoad ईवेंट हैंडलर कहा जाता है जिसमें से मैं this.Close()
  5. OnFormClosing विधि कॉल करता है lled
  6. FormClosing ईवेंट हैंडलर कहा जाता है
  7. Dispose मेरी फार्म पर कहा जाता है और सभी यह है उपयोगकर्ता

को नियंत्रित करता है और उसके बाद Control.Show() विधि के अंत में कहीं न कहीं, यह फार्म के लिए एक संभाल पाने की कोशिश करता है , जो बाहर निकलता है और अपवाद फेंकता है क्योंकि ऑब्जेक्ट को डिस्पोजेड चिह्नित किया जाता है।

मेरा असली सवाल यह है कि, मैं बिना किसी अपवाद के मेरे अन्य रूपों पर यह वही चीज़ क्यों कर सकता हूं? क्या यह एक जीसी मुद्दा है? मैंने GC.Collect()this.Close() के ठीक बाद कॉल करने का प्रयास किया है और इससे कोई फर्क नहीं पड़ता। जैसे मैंने कहा, यह इस फ़ॉर्म पर 100% समय होता है, और कभी भी कहीं भी नहीं, बच्चे के उपयोगकर्ता नियंत्रण, फॉर्म चर का दायरा, आदि

कोई विचार?

उत्तर

7

मुझे पता है कि यह एक पुराना मुद्दा है लेकिन किसी ने भी obvoius जवाब पोस्ट नहीं किया था।

आप कहते हैं कि आप Control.Show() पर कॉल करें और फिर Form.Close() और फिर फॉर्म का निपटान किया गया है। खैर, जब तक कि आप एमडीआई का उपयोग न करें या ShowDialog का उपयोग न करें, जैसा कि दस्तावेज है। हालांकि, Close() दस्तावेज़ीकरण का संक्षिप्त संस्करण "फॉर्म बंद करता है", यह वास्तव में कुछ स्थितियों के तहत इसे पूरी तरह से निपटाता है।आप एक फार्म फिर से दिखाना चाहते हैं तो http://msdn.microsoft.com/en-us/library/system.windows.forms.form.close.aspx

:

टिप्पणी अनुभाग देखें। Close() के बजाय Hide() विधि का उपयोग करें।

आशा है कि अन्य खोज आत्माओं की सहायता करें।

और दोस्तों, "मुझे नहीं पता कि यह कभी-कभी क्यों काम करता है" पर खोजना बंद नहीं करते हैं। यह बहुत ही रक्षात्मक के साथ छोटी गाड़ी सॉफ्टवेयर बन जाता है "मैं इस विधि को फिर से" सामान में कॉल करूंगा। अच्छा नही।

+0

दुर्भाग्यवश मैं विंडोज देव नहीं करता हूं, लेकिन यह सही लगता है। धन्यवाद! – LoveMeSomeCode

+0

.Net2.0 – Vadim

0

मुझे ऐसा लगता है, इस पर बारीकी से देख के बिना, पूरा है कि स्पष्ट तरीका है कि क्या आप एक कस्टम प्रपत्र Form से पाने वर्ग बनाने के लिए हो सकता है चाहते हैं, और OnFormLoad(...) ओवरराइड और/या Show() अपनी हालत के लिए जाँच करने के लिए और रद्द जल्दी बाहर

उसने कहा, मुझे नहीं पता कि यह कभी-कभी क्यों काम करेगा और दूसरी बार क्यों नहीं।

+0

असल में, यह मामला यहां है। मैंने इसका उल्लेख नहीं किया बी/सी मेरे सभी रूप इस तरह हैं। मूल रूप OnFormLoad और OnFormClose को ओवरराइड करता है, लेकिन यह उन विधियों में रजिस्ट्री सामग्री करता है। कॉल अनुक्रम सभी रूपों में समान है। – LoveMeSomeCode

1

एक संभावना:

वे इस फार्म पर एक टाइमर हो सकता है, कि प्रारंभ किया जा रहा है और उनके FormLoad घटना में सक्षम होना चाहिए। फॉर्म बंद होने से पहले टाइमर को अक्षम और बंद कर दिया जाना चाहिए, अगर टाइमर निकाल दिया जाता है तो फॉर्म को एक्सेस करने का प्रयास कर रहा है।

मैं रूपों को देखा है कि ऐसा करने से पहले ...

+0

अच्छा विचार, लेकिन इस फ़ॉर्म पर कोई टाइमर नहीं है। हालांकि कई उपयोगकर्ता नियंत्रण, लेकिन मैंने यह सुनिश्चित करने के लिए जांच की कि उनके सभी निपटान विधियों को बुलाया जा रहा है। – LoveMeSomeCode

3

लोड घटना में वास्तव में अच्छा विचार प्रपत्र बंद नहीं है। सक्रिय घटना के बाद ऐसा करें।

0

क्या आपने यह देखने के लिए .NET कोड में कदम उठाने का प्रयास किया है कि अपवाद होने पर कोड की किस पंक्ति को बुलाया जा रहा है? यदि आपके पास वीएस 2008 है तो आप टूल्स -> विकल्प -> डिबगिंग पर जाकर ऐसा कर सकते हैं और .NET Framework Source Stepping सक्षम करें का चयन कर सकते हैं। चेतावनी दीजिये, इसमें सभी आवश्यक फ़ाइलों को डाउनलोड करने में कुछ समय लग सकता है, लेकिन इस तरह आप फॉर्म में कदम उठा सकते हैं। दिखाएं() और देखें कि क्या हो रहा है।

+0

नहीं, मेरी इच्छा है। मैं वीएस 2005 का उपयोग कर रहा हूं। मैंने हालांकि परावर्तक की जांच की है, और यह कॉल स्टैक की तरह ही कहता है: नियंत्रण के अंत के ठीक नीचे। इसे फोकसएक्टिव कंट्रोल इन्टरनेट कहते हैं, जो हैंडल गेटर को कॉल करता है, जो अपवाद को फेंकने पर अपवाद फेंकता है। – LoveMeSomeCode

5

ठीक है, मेरे अपने प्रश्न का उत्तर देने से नफरत है, लेकिन यह मुझे पागल कर रहा था, और यह मैंने कभी देखा है कि पुन: उत्पन्न करने के लिए सबसे कठिन कीड़े में से एक था।

मेरे फॉर्म पर मैं ऑनफॉर्मलोड और ऑनफॉर्मक्लोज़ विधियों को ओवरराइड कर रहा हूं, जहां मैं रजिस्ट्री से/फॉर्म के आकार, स्थान और विंडोस्टेट को सहेज/पुनर्स्थापित करता हूं। मैंने यह कोड निकाला और यह समस्या ठीक कर दी। अजीब बात यह है कि, मैंने इसे वापस रखा और समस्या वापस नहीं आई।

मैंने अंततः समस्या को पुन: उत्पन्न किया: आपको फ़ॉर्म को पूरी तरह से खोलने, इसे अधिकतम करने, और फिर इसे बंद करने की आवश्यकता है ताकि अधिकतम स्थिति रजिस्ट्री में सहेजी जा सके। फिर जब आप इसे फिर से खोलते हैं, तो यह इसे अधिकतम करने के लिए सेट कर देगा, और यदि यह लोड हैंडलर में बंद हो जाता है, तो यह आकार/स्थान को बंद होने के रूप में एक्सेस करने का प्रयास करता है। OnFormClosing विधि में स्पष्ट रूप से इन मानों तक पहुंचने से फ़ॉर्म को ध्यान केंद्रित करने का प्रयास किया जाता है और केवल अगर फॉर्म को अधिकतम किया गया है, जो अवैध है, क्योंकि फ़ॉर्म का निपटारा किया गया है।

तो मूल रूप से, आप एक फार्म के OnFormClosing विधि में पर्चा प्रदर्शन गुण अभिगमन नहीं कर सकते कि प्रपत्र इसे से बंद कॉल करने के लिए जा रहा है लोड घटना है। (जब तक आप निपटाई गई जाँच सहारा पहले)

सुंदर Winforms ज्ञान का विशिष्ट टुकड़ा मुझे पता है, लेकिन मैं इसे वैसे भी लिख रहा हूँ।

0

ठीक है, यह पता चला है कि यह थोड़ा सा सरल और अधिक सामान्य है, लेकिन मैंने अभी भी अजीब और अस्पष्ट है।

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

मेरा सिर दर्द होता है।

0

फॉर्म। दिखाया गया() चाल भी है।

22

सबसे अच्छा तरीका है ऐसा करने के लिए:

this.BeginInvoke(new MethodInvoker(this.Close)); 

यह सबसे आसान तरीका आप अभ्यस्त ObjectDisposedException

+1

में काम न करें .Net2.0 – Vadim

3

मिल आप एक फार्म बंद करने के लिए चाहते हैं के रूप में यदि उपयोगकर्ता ऊपर दाईं ओर स्थित पार दबाया है कोने (आमतौर पर रद्द करने का मतलब है), बस निम्न कोड जोड़ें।

this.DialogResult = System.Windows.Forms.DialogResult.Cancel; 
this.Close(); 

यह भी प्रपत्र लोड समारोह में काम करता है:

private void MyForm_Load (object sender, EventArgs e) 
{ 
    // do some initializations 

    if (!ContinueLoadingForm()) 
    { 
     this.DialogResult = System.Windows.Forms.DialogResult.Cancel; 
     this.Close(); 
     return; 
    } 
    // continue loading the form 
} 

आप प्रपत्र के थोड़े समय तक दिखाई दे सकता है नहीं करना चाहते हैं, डिजाइनर में दृश्यमान संपत्ति झूठी (उदाहरण के लिए सेट या कन्स्ट्रक्टर), और जब आप निश्चित हैं कि प्रोग्राम लोडिंग जारी रख सकता है तो इसे वापस सत्य पर सेट करें।

+0

में अच्छा काम करता है हालांकि एक पल के लिए प्रदर्शित होने वाले फॉर्म से बचने के लिए प्रतीत नहीं होता है। –

0

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

यह मुद्दा भी कुछ हिस्सों में है कि यदि कोड में कहीं और, आप इस रूप में फॉर्म या नियंत्रण की संपत्ति तक पहुंच रहे हैं, जो फ़ॉर्म को बंद होने से रोक सकता है।

यह सुझाव दिया जा सकता है कि जैसा कि सुझाव दिया गया है, आपके पास संपत्ति है उदा।

private bool _loadedOk = false; 

आपके प्रारंभिक कोड में आपके द्वारा सेट किए गए फॉर्म में। Form_Loaded के बाद के बाद की घटनाओं में से एक में, फिर आप इससे पूछताछ करते हैं और फ़ॉर्म को बंद करते हैं तो यह गलत है।

शायद कोई ऐसा करने के लिए सबसे अच्छी घटना का सुझाव दे सकता है ??

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