2014-03-25 60 views
1

我已經創建了一個自定義類,它使用繼承面板,圖片框和兩個標籤,這些標籤充當表單上的「圖標」,供用戶在整個應用程序中單擊和導航。我這樣做是因爲它給人一種更好的圖形印象,並且比單獨一個按鈕更具可定製性。面板控件上的緩慢顏料

我已經包含了一個類從以下CodeProject上(它們畫到面板,使面板看起來就像是有圓角)繪製圓角矩形: http://www.codeproject.com/Articles/5649/Extended-Graphics-An-implementation-of-Rounded-Rec

在問候畫畫,我已經有線我MouseEnter和MouseLeave事件來切換布爾值,然後調用me.invalidate()根據事件設置的布爾值重繪面板背景。我的代碼重繪的樣子:

If mouseoverBool Then 'class variable mouseoverBool set by mouseenter/mouseleave to true/false 

     Dim g As Graphics = e.Graphics 
     g.SmoothingMode = SmoothingMode.AntiAlias 
     Dim brush As New LinearGradientBrush(New Point(Me.Width/2, 0), New Point(Me.Width/2, Me.Height), Color.LightSteelBlue, Color.LightBlue) 
     g.FillRoundedRectangle(brush, 0, 0, Me.Width - 1, Me.Height, 10) 
     g.FillRoundedRectangle(New SolidBrush(Color.FromArgb(100, 118, 173, 218)), 0, 0, Me.Width, Me.Height, 10) 
     g.DrawRoundedRectangle(New Pen(ControlPaint.Light(SystemColors.InactiveBorder, 0.0F)), 0, 0, Me.Width - 1, Me.Height - 1, 10) 

    Else 

     Dim g As Graphics = e.Graphics 
     g.SmoothingMode = SmoothingMode.AntiAlias 
     Dim brush As New LinearGradientBrush(New Point(Me.Width/2, 0), New Point(Me.Width/2, Me.Height), SystemColors.GradientInactiveCaption, ControlPaint.Dark(SystemColors.GradientActiveCaption, 0.5F)) 
     g.FillRoundedRectangle(brush, 0, 0, Me.Width - 1, Me.Height, 10) 
     g.FillRoundedRectangle(New SolidBrush(Color.FromArgb(100, 118, 173, 218)), 0, 0, Me.Width, Me.Height, 10) 
     g.DrawRoundedRectangle(New Pen(ControlPaint.Light(SystemColors.InactiveBorder, 0.0F)), 0, 0, Me.Width - 1, Me.Height - 1, 10) 

     End If 

或者在C#:

if (mouseoverBool) { 

Graphics g = e.Graphics; 
g.SmoothingMode = SmoothingMode.AntiAlias; 
LinearGradientBrush brush = new LinearGradientBrush(new Point(this.Width/2, 0), new Point(this.Width/2, this.Height), Color.LightSteelBlue, Color.LightBlue); 
g.FillRoundedRectangle(brush, 0, 0, this.Width - 1, this.Height, 10); 
g.FillRoundedRectangle(new SolidBrush(Color.FromArgb(100, 118, 173, 218)), 0, 0, this.Width, this.Height, 10); 
g.DrawRoundedRectangle(new Pen(ControlPaint.Light(SystemColors.InactiveBorder, 0f)), 0, 0, this.Width - 1, this.Height - 1, 10); 

} else { 

Graphics g = e.Graphics; 
g.SmoothingMode = SmoothingMode.AntiAlias; 
LinearGradientBrush brush = new LinearGradientBrush(new Point(this.Width/2, 0), new Point(this.Width/2, this.Height), SystemColors.GradientInactiveCaption, ControlPaint.Dark(SystemColors.GradientActiveCaption, 0.5f)); 
g.FillRoundedRectangle(brush, 0, 0, this.Width - 1, this.Height, 10); 
g.FillRoundedRectangle(new SolidBrush(Color.FromArgb(100, 118, 173, 218)), 0, 0, this.Width, this.Height, 10); 
g.DrawRoundedRectangle(new Pen(ControlPaint.Light(SystemColors.InactiveBorder, 0f)), 0, 0, this.Width - 1, this.Height - 1, 10); 

} 

問題發生的歷史是,面板內的標籤和圖片框(設置爲透明背景的所有控件)是緩慢的刷新自己的背景第一次任何自定義的「圖標」面板繪製背景。面板繪製,然後等半秒鐘後,標籤和picturebox上的背景終於更新。我認爲這是發生的,因爲調用.invalidate()會強制自定義面板重新繪製,然後再後續所有控件。我在一個「無縫」油漆之後,整個控件都一次塗上油漆,包括標籤和picturebox。我應該如何試圖實現這一目標?

+0

很難猜測黑洞吞噬了10億個cpu週期,這些片段是沒用的。在工具箱中的所有控件中,標籤和圖片框位於浪費小工具的列表之上。通過使用TextRenderer.DrawText()和Graphics.DrawImage()替換標籤,您可以獲得「無縫」繪畫和無問題透明度。 –

+0

它不應該這麼慢。如果你想*無縫塗料*你應該做所有的繪製自己。 –

+0

@HansPassant您想提供您的評論作爲答案嗎?你所說的真的是(一如既往)。我最終按照建議自己繪製控制,它像一個魅力。 –

回答

0

我在自定義面板中使用了2個標籤和一個圖片框來顯示文本和圖片。正如在評論中指出的,你可以很容易地自己繪製這些項目(這不僅更快,而且更好理解,因爲你必須首先使用控件處理所有控件的mouseEnter/mouseLeave事件),這會停止閃爍從發生。

由於我已經創建了用於保存圖像和標籤文本(與前面的控件一起使用)的屬性,所以很容易將其轉換爲我的自定義面板的繪製事件。

e.Graphics.DrawString(Me.txtHeaderDescription, New Font("Calibri", 12, FontStyle.Italic), Brushes.White, New Point(105, 15)) 

    Dim sf As New StringFormat 
    sf.Alignment = StringAlignment.Near 
    Dim Rectf As RectangleF = New Rectangle(105, 35, 200, 75) 
    e.Graphics.DrawString(Me.txtDescription, New Font("Calibri", 8, FontStyle.Regular), Brushes.White, Rectf, sf) 

    e.Graphics.DrawImage(Me.MyImage, 5, 3, 96, 96)