Reputation: 280
I have used the following code to create a groupbox with colored borders:
Public Class BorderGroupBox
Inherits GroupBox
Private _borderColor As Color
Private _borderWidth As Integer
Private _borderStyle As ButtonBorderStyle
...
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
Dim tSize As Size = TextRenderer.MeasureText(Me.Text, Me.Font)
Dim borderRect As Rectangle = e.ClipRectangle
borderRect.Y = CInt((borderRect.Y + (tSize.Height / 2)))
borderRect.Height = CInt((borderRect.Height - (tSize.Height / 2)))
ControlPaint.DrawBorder(e.Graphics, borderRect, _borderColor, _borderWidth, _borderStyle, BorderColor, _borderWidth, _borderStyle, BorderColor, _borderWidth, _borderStyle, BorderColor, _borderWidth, _borderStyle)
Dim textRect As Rectangle = e.ClipRectangle
textRect.X = (textRect.X + 6)
textRect.Width = tSize.Width + 6
textRect.Height = tSize.Height
e.Graphics.FillRectangle(New SolidBrush(Me.BackColor), textRect)
e.Graphics.DrawString(Me.Text, Me.Font, New SolidBrush(Me.ForeColor), textRect)
End Sub
End Class
The problem is, it is placed inside a scrollable container, and if it is scrolled the border isn't redrawn correctly:
Upvotes: 3
Views: 18289
Reputation: 33
you have to use Me.ClientRectangle instead of Me.DisplayRectangle for boder and text. If you using old way then flicker issue not solve and text of group box will not display.
Upvotes: 0
Reputation: 11
This class allows the border to be set for all of your boxes or individually by adding a border color control to the properties tab for the group box.
Public Class GroupBoxA
Inherits GroupBox
Private _borderColor As Color
Public Sub New()
MyBase.New()
Me._borderColor = Color.OrangeRed
End Sub
Public Property BorderColor() As Color
Get
Return Me._borderColor
End Get
Set(ByVal value As Color)
Me._borderColor = value
End Set
End Property
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
Dim tSize As Size = TextRenderer.MeasureText(Me.Text, Me.Font)
Dim borderRect As Rectangle = Me.DisplayRectangle
borderRect.Y = (borderRect.Y + (tSize.Height / 2))
borderRect.Height = (borderRect.Height - (tSize.Height / 2))
ControlPaint.DrawBorder(e.Graphics, borderRect, Me._borderColor,
ButtonBorderStyle.Solid)
Dim textRect As Rectangle = Me.DisplayRectangle
textRect.X = (textRect.X + 6)
textRect.Width = tSize.Width
textRect.Height = tSize.Height
e.Graphics.FillRectangle(New SolidBrush(Me.BackColor), textRect)
e.Graphics.DrawString(Me.Text, Me.Font, New SolidBrush(Me.ForeColor), textRect)
End Sub
End Class
Upvotes: 1
Reputation: 941217
You can get it to misbehave a lot worse than that:
This goes wrong because of your code using e.ClipRectangle. Note that it appears twice in your snippet. That variable does not give you the border rectangle. It tells you how much of your client area needs to be re-drawn. It is an optimization opportunity, you can draw less by omitting the parts of the client area that don't need to be refreshed.
It is usually the same size as the display rectangle, which is why it looked like it worked just fine. But not when you put it inside a scrollable container, Windows optimizes scrolls by blitting the parts of the client area that simply can be moved. And then generates a paint for the parts that are revealed by the scroll. With a small e.ClipRectangle. You can see that in the screenshot, note the small rectangles.
Replace e.ClipRectangle with Me.DisplayRectangle.
Upvotes: 6