2012-02-03 13 views
6

मेरे पास कुछ कस्टम (Winforms) घटक हैं जो GDI + का उपयोग कर स्क्रीन पर आते हैं।डबल ऐपिंग को मेरे ऐप को मारने का कारण क्या हो सकता है?

रीपेंट पर झिलमिलाते रोकने के लिए, मैं डबल बफरिंग सक्षम करने के लिए फैसला किया है, इसलिए मैं अपने निर्माता के लिए एक लाइन कहा:

public ColourWheel() 
{ 
    InitializeComponent(); 
    this.DoubleBuffered = true; 
} 

कौन इस घटक (ColourWheel) पर ठीक काम करता है।

  1. जब मैं पर घटक के साथ एक फार्म चलाने का प्रयास, मैं एक मिल: जब मैं अपने अन्य दो (इसी तरह संरचित) घटकों में से किसी के निर्माता के लिए एक ही पंक्ति जोड़ने के लिए, मैं अजीब लक्षण की एक जोड़ी मिल Application.Run(new Form()); पर तर्क अपवाद।
  2. यदि मैं डिज़ाइन मोड पर स्विच करता हूं, तो मुझे पैरामीटर के साथ एक अनचाहे अपवाद वाले घटक के बारे में त्रुटि मिलती है।

इससे कोई फर्क नहीं पड़ता कि मैं एक या सभी पर डबल बफरिंग कर रहा हूं, फिर भी यह कलरव्हील पर काम करता है, लेकिन दूसरों को नहीं।

रिकॉर्ड के लिए, मैंने कुछ अन्य doublebuffering तकनीकों का भी प्रयास किया है।

एक घटक पर काम करने के लिए डबल बफरिंग का कारण क्या हो सकता है, लेकिन दूसरों को नहीं?


संपादित करें: यहाँ रन-टाइम लक्षण से अपवाद विवरण दिया गया है:

System.ArgumentException था बिना क्रिया संदेश = पैरामीटर मान्य नहीं है। स्रोत = System.Drawing StackTrace: System.Drawing.BufferedGraphics.Render() पर System.Drawing.Graphics.GetHdc() System.Drawing.BufferedGraphics.RenderInternal पर (HandleRef refTargetDC, BufferedGraphics बफर) पर System.Windows पर .Forms.Control.WmPaint (संदेश & मी) System.Windows.Forms.Control.WndProc (संदेश & मी) पर System.Windows.Forms.ScrollableControl.WndProc पर (संदेश & मी) System.Windows.Forms पर System.inds.Forms.Co ntrol.ControlNativeWindow.WndProc (संदेश & मी) System.Windows.Forms.NativeWindow.DebuggableCallback (IntPtr hWnd, Int32 संदेश, IntPtr wParam, IntPtr lParam) पर System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW पर (एमएसजी & संदेश) System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop (IntPtr dwComponentID, Int32 कारण Int32 pvLoopData) System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner पर (Int32 पर कारण, ApplicationContext संदर्भ) System.Windows.Forms.Aplication.ThreadContext.RunMessageLoop (Int32 कारण, अनुप्रयोग कॉन्टेक्स्ट संदर्भ) एस पर ystem.Windows.Forms.Aplication.Run (फॉर्म मुख्यफॉर्म) TestForm.Program पर।मुख्य() में डी: \ दस्तावेज़ और सेटिंग्स \ टॉम राइट \ मेरे दस्तावेज़ \ विजुअल स्टूडियो 2010 \ प्रोजेक्ट्स \ कलरपिकर \ टेस्टफॉर्म \ Program.cs: सिस्टम 18.सिस्टम पर। AppDomain._nExecuteAssembly (RuntimeAssembly असेंबली, स्ट्रिंग [] args) System.AppDomain.ExecuteAssembly (स्ट्रिंग assemblyFile, साक्ष्य assemblySecurity, स्ट्रिंग [] args) Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() पर System.Threading.ThreadHelper.ThreadStart_Context (वस्तु राज्य) पर System.Threading पर पर .ExecutionContext.Run (ExecutionContext executionContext, ContextCallback कॉलबैक, वस्तु राज्य, बूलियन ignoreSyncCtx) System.Threading.ExecutionContext.Run (ExecutionContext executionContext, ContextCallback कॉलबैक, वस्तु राज्य) पर System.Threading.ThreadHelper.ThreadStart पर() InnerException:


संपादित करें 2: एक (और अधिक जटिल) के दो घटक है कि से OnPaint हैंडलर उत्पन्न कर रहे हैं समस्याओं:

private void ValueSlider_Paint(object sender, PaintEventArgs e) 
{ 
     using (Graphics g = e.Graphics) 
     { 
      g.DrawImage(this.gradientImage, new Rectangle(0, 0, paintArea.Width, paintArea.Height)); 
      if (this.showmarker) 
      { 
       ColourHandler.HSV alt = ColourHandler.RGBtoHSV(new ColourHandler.RGB(this.SelectedColour.R, this.SelectedColour.G, this.SelectedColour.B)); 
       alt.Saturation = 0; 
       alt.value = 255 - alt.value; 
       using (Pen pen = new Pen(ColourHandler.HSVtoColour(alt))) 
       { 
        pen.Width = (float)MARKERWIDTH; 
        g.DrawRectangle(pen, 0 - pen.Width, this.brightnessPoint.Y - MARKERWIDTH, this.paintArea.Width + (pen.Width * 2), MARKERWIDTH * 2); 
       } 
      } 
     } 
} 
+0

कृपया अपवाद साझा करें। – roken

+1

@roken सब तुम्हारा दोस्त मेरे दोस्त। –

+0

क्या आप अपमानजनक नियंत्रण में OnPaint() को ओवरराइड कर रहे हैं? यदि हां, तो यह कैसा दिखता है? – roken

उत्तर

8

आपको ऑब्जेक्ट को Paint ईवेंट के दौरान आपको ऋण देने का अनुमान नहीं लगाया जाना चाहिए, और यही है कि आपका using ब्लॉक अनुचित तरीके से करता है।

लक्षण है कि अगली बार जब Paint घटना आग, आप एक ही Graphics वस्तु वापस पाने के लिए है, लेकिन यह अब के लिए बाध्य है एक में स्मृति HDC, के रूप में अपने स्टैक ट्रेस में देखा Graphics.GetHdc() को विफल कर रही।

  1. ऐसा नहीं है कि यह एक एकल Paint घटना बाद भी जीवित रहता संभव है (और यह बहुत संभावना डबल बफरिंग के साथ मामला है, हालांकि यह भी एकल बफरिंग के साथ संभव है यदि CS_OWNDC खिड़की शैली सेट कर दिया जाता है)।

  2. Paint ईवेंट के लिए एक से अधिक हैंडलर हो सकते हैं।

तो, ईवेंट हैंडलर्स Graphics वस्तुओं पर Dispose कॉल या एक using ब्लॉक ऐसा करने के लिए अनुमति नहीं देनी चाहिए। इसके बजाए, .NET Framework Paint ईवेंट हैंडलिंग पूर्ण होने के बाद उचित संसाधनों को साफ़ करता है।

+1

यह एक साल से अधिक समय तक काम करता था, जब मैंने उपयोगकर्ता नियंत्रण वर्ग को अपनी फाइल में स्थानांतरित कर दिया तो त्रुटि ओपी को फेंकना शुरू कर दिया। आपने जो सुझाव दिया है - सी # वास्तव में कभी-कभी अजीब हो सकता है! –

1

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

+2

मुझे नहीं लगता कि आपको 'पेंट' ईवेंट के दौरान आपको दी गई 'ग्राफिक्स' ऑब्जेक्ट का निपटान करना होगा। –

+0

@ben सही है। 'G' पर 'उपयोग' न करें, क्योंकि जब आप उस दायरे से बाहर निकलते हैं तो यह ग्राफ़िक्स ऑब्जेक्ट का निपटान करेगा, लेकिन आप उस ऑब्जेक्ट का'owner 'नहीं हैं। –

+0

धन्यवाद दोस्तों। मैं 'ग्राफिक्स जी = ई ग्राफिक्स) {} 'का उपयोग कर रहा था। इसे हटाने की कुंजी थी। –