2012-02-03 58 views
6

我有幾個使用GDI +繪製到屏幕上的自定義(winforms)組件。什麼可能導致Double Buffering殺死我的應用程序?

爲了防止閃爍的重繪,我決定啓用雙緩衝,所以我加了一條線,我的構造函數:

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

該組件(ColourWheel)上正常工作。當我同行添加到任何我的另外兩個(類似結構的)部件的構造函數中,我得到了幾個奇怪的症狀:

  1. 當我嘗試與部件運行的形式,我得到一個參數例外Application.Run(new Form());
  2. 如果我切換到設計模式,我得到一個關於組件有一個未處理的異常與一個參數有關的錯誤。

我是不是在將一個或所有的緩衝區變成雙緩衝區,它仍然可以在ColourWheel上工作,但不是其他的。

爲了記錄,我也嘗試了其他一些doublebuffering技術。

什麼可能導致雙緩衝工作在一個組件上,而不是其他工作?


編輯:下面是從運行時症狀異常詳細信息:

System.ArgumentException是未處理消息=參數不 有效。源= System.Drawing中堆棧跟蹤: 在System.Drawing.Graphics.GetHdc() 在System.Drawing.BufferedGraphics.RenderInternal(HandleRef refTargetDC,BufferedGraphics緩衝液) 在System.Drawing.BufferedGraphics.Render() 在System.Windows .Forms.Control.WmPaint(消息&米) 在System.Windows.Forms.Control.WndProc(消息&米) 在System.Windows.Forms.ScrollableControl.WndProc(消息&米) 在System.Windows.Forms的.UserControl.WndProc(Message & m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message & m) at System.Windows.Forms.Co ntrol.ControlNativeWindow.WndProc(消息&米) 在System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr的的HWND,MSG的Int32,IntPtr的WPARAM,IntPtr的LPARAM) 在System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG & MSG) 在System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr的 dwComponentID,的Int32原因,的Int32 pvLoopData) 在System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(的Int32 原因,ApplicationContext上下文) at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason,ApplicationContext context) at S ystem.Windows.Forms.Application.Run(Form mainForm) at TestForm.Program。Main()in D:\ Documents and Settings \ Tom Wright \ My Documents \ Visual Studio 2010 \ Projects \ ColourPicker \ TestForm \ Program.cs:line 18 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly,String [] args) 在System.AppDomain.ExecuteAssembly(字符串assemblyFile,證據assemblySecurity,字串[] args) 在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在System.Threading.ThreadHelper.ThreadStart_Context(對象狀態) 在的System.Threading .ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回調,對象狀態,Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state) 在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 2012-02-03 19:48:48

+1

@roken你的朋友。 – 2012-02-03 19:54:02

+0

您是否在違規控件中重寫OnPaint()?如果是這樣,那是什麼樣子? – roken 2012-02-03 20:52:30

回答

8

Paint事件期間,您不應該處置借給您的Graphics對象,這就是您的using阻止的不當行爲。

的症狀是下一次Paint事件觸發,你會得到同樣Graphics對象回來,但它不再綁定到一個內存HDC,導致在你的堆棧跟蹤看到Graphics.GetHdc()失敗。

  1. 這是可能的,它會超越單一Paint事件(這是很可能與雙緩衝的情況下,雖然它也可以用單緩衝如果CS_OWNDC窗口樣式設置)。

  2. Paint事件可以有多個處理程序。

因此,事件處理程序不應該呼籲Graphics對象Dispose或允許using塊這樣做。相反,在框架Paint事件處理完成後,.NET框架會根據需要清理資源。

+1

它工作了一年,然後當我將用戶控件類移到它自己的文件開始拋出錯誤OP在這裏得到。你建議的工作 - 有時候C#可能真的很奇怪! – 2014-04-08 07:25:36

1

你應該在另一臺機器上測試它,看它是否只是你的電腦。大多數情況下,這不應該由於雙緩衝而發生,而是檢查是否正在處理不應該在Paint事件中的任何元素,或者在代碼中執行任何會執行兩次的問題。

+2

我不認爲你應該在'Paint'事件期間處理給你的'Graphics'對象。 – 2012-02-03 20:34:49

+0

@ben是對的。不要在'g'上做一個'使用',因爲當你退出該範圍時,它將處理Graphics對象,但你不是該對象的'所有者'。 – 2012-02-04 10:06:55

+0

謝謝你們。我在做'使用(Graphics g = e.Graphics){}'。解決這個問題是關鍵。 – 2012-02-04 10:21:11

相關問題