2014-12-01 79 views
0

情景子類組合框中不能正確繪製內容

的WinForms,我有子類一GroupBox更改此控件的邊框顏色。

問題

設計模式(在視覺建設者的VisualStudio的),如果我進行任何更改控制我Groupbox裏面可以說每個點擊控制變化在TEXTFONT然後我Groupbox重繪控制是這樣的:

enter image description here

注意:使控件無效後,它會再次正確重繪。

問題

這是一個已知的問題時,業主繪製存儲控制集合像GroupBox的容器?

我錯過了OnPaint方法來解決這個繪畫問題嗎?

CODE

VB版本:

​​

C#版本:

/// <summary> 
/// Handles the <see cref="E:Paint"/> event. 
/// </summary> 
/// <param name="e">A <see cref="T:PaintEventArgs"/> that contains the event data.</param> 

protected override void OnPaint(PaintEventArgs e) 
{ 
    // MyBase.OnPaint(e) 
    this.DrawBorder(e); 

/// <summary> 
/// Draws a border on the control surface. 
/// </summary> 

private void DrawBorder(PaintEventArgs e) 
{ 
    // The groupbox header text size. 
    Size textSize = TextRenderer.MeasureText(this.Text, this.Font); 

    // The width of the blankspace drawn at the right side of the text. 
    int blankWidthSpace = 3; 

    // The thex horizontal offset. 
    int textOffset = 7; 

    // The rectangle where to draw the border. 
    Rectangle borderRect = e.ClipRectangle; 
    var _with1 = borderRect; 
    _with1.Y = _with1.Y + (textSize.Height/2); 
    _with1.Height = _with1.Height - (textSize.Height/2); 

    // The rectangle where to draw the header text. 
    Rectangle textRect = e.ClipRectangle; 
    var _with2 = textRect; 
    _with2.X = _with2.X + textOffset; 
    _with2.Width = (textSize.Width - blankWidthSpace); 
    _with2.Height = textSize.Height; 

    // Draw the border. 
    ControlPaint.DrawBorder(e.Graphics, borderRect, this.borderColor1, this.borderStyle1); 

    // Fill the text rectangle. 
    e.Graphics.FillRectangle(new SolidBrush(this.BackColor), textRect); 

    // Draw the text on the text rectangle. 
    textRect.Width = textSize.Width + (blankWidthSpace * 2); 
    // Fix the right side space. 
    e.Graphics.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), textRect); 

} 

//======================================================= 
//Service provided by Telerik (www.telerik.com) 
//======================================================= 
+0

什麼是'borderStyle1'?這不是我期望看到的那樣。確保子控件沒有邊框。圖片中的黃色是什麼 - 它是轉載的標題嗎? – Plutonix 2014-12-01 21:22:58

+0

@Plutonix感謝您的評論。 1)arg是一個ButtonBorderStyle:http://msdn.microsoft.com/en-us/library/system.windows.forms.controlpaint.drawborder%28v=vs.110%29.aspx 2)是的,似乎是黃色標題被重新繪製在內部控件的位置(並且組框邊框也被重新繪製),我不知道爲什麼會發生這種情況:( – ElektroStudios 2014-12-01 21:57:03

+0

我不認爲它是顯示的代碼的結果 – Plutonix 2014-12-01 22:10:04

回答

1

實際上,有幾件事情你的代碼錯誤和方法:

' The rectangle where to draw the border. 
Dim borderRect As Rectangle = e.ClipRectangle 
' and: 
' The rectangle where to draw the header text. 
Dim textRect As Rectangle = e.ClipRectangle 

如果您選擇一個子控件並稍微移動它,您將會看到圖像顯示的問題。原因在於Windows不會要求控件重新繪製整個自己以進行如此小的更改。相反,它使子控件周圍的一個小區域無效,並將其作爲ClipRectangle傳遞給它。在某些情況下,它實際上並不正確。

因此,根據e.ClipRectangle定位GroupBox邊框矩形將在剛剛移動的控件周圍區域的頂部繪製邊框和Caption的一部分。使用Bounds調整爲各種事情


這應該擺脫提到的問題,但它會發現其他幾個人。例如,如果主題或樣式需要3D類型邊框,則會繪製2條邊框線,並且您的計算更多依賴於航位推算。

接下來,我不確定Control.DrawBorder是完全適合的,如果您嘗試覆蓋默認行爲。這將尊重某些由主題/樣式等決定的事情,這些都是你試圖重寫的內容。

我還可以使用TextRenderer使標題更好地顯示。

要做你想做的事情,你很可能不得不接管default GroupBoxRenderer所做的一切。如果您將bordercolor更改爲White或Fuschia之類的東西,則會看到正常的渲染仍在進行,您的代碼只是試圖將其繪製在頂部。

即使你有這個工作FlatStyleColor,主題或因爲你的代碼正在採取這些方法都考慮風格會失敗一些其他組合。

下面是我用的,但它只是導致捶痣與所產生的不同問題進行遊戲:

Dim textRect As New Rectangle With {.X = 0, 
            .Y = 2, 
            .Height = textSize.Height, 
            .Width = (textSize.Width - blankWidthSpace) 
            } 
Dim borderRect As New Rectangle With {.X = 1, .Y = (textSize.Height \ 2) + 1, 
           .Width = Bounds.Width - 2, 
           .Height = Bounds.Height - (textSize.Height \ 2) - 2} 

TextRenderer.DrawText(e.Graphics, " " & MyBase.Text & " ", MyBase.Font, 
          textRect, MyBase.ForeColor, MyBase.BackColor) 

這似乎與你的other question約「醜陋白色邊框」。試圖修復或重寫一個主題通過繼承(一堆)控制(s)不是最好的方式來解決它。

我會考慮提供一個適合你的口味的替代Aero風格的主題。此外,你是誰說所有的用戶都會同意它是「醜陋的」(我認爲這會讓表單看起來很忙,但不完全「醜陋」)。

+0

我認爲可以理解爲「醜陋」的背景,它對我來說很醜陋,在我的意見,其餘的我只能說謝謝! – ElektroStudios 2014-12-04 09:14:13