Групповой блок Winforms с цветной рамкой
Я использовал следующий код для создания группового блока с цветными рамками:
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
Проблема в том, что он находится внутри прокручиваемого контейнера, и если он прокручивается, граница перерисовывается неправильно:
3 ответа
Вы можете заставить его плохо себя вести:
Это идет не так, потому что ваш код использует e.ClipRectangle. Обратите внимание, что он появляется дважды в вашем фрагменте. Эта переменная не дает вам прямоугольник границы. Он говорит вам, сколько из вашей клиентской области необходимо перерисовать. Это возможность оптимизации, вы можете рисовать меньше, опуская части клиентской области, которые не нужно обновлять.
Как правило, он имеет такой же размер, как и прямоугольник дисплея, поэтому он выглядел так, как будто работал нормально. Но не тогда, когда вы помещаете его в прокручиваемый контейнер, Windows оптимизирует прокрутки, разбивая части клиентской области, которые просто могут быть перемещены. И затем генерирует краску для частей, которые обнаруживаются свитком. С маленьким e.ClipRectangle. Вы можете видеть это на скриншоте, обратите внимание на маленькие прямоугольники.
Замените e.ClipRectangle на Me.DisplayRectangle.
Этот класс позволяет устанавливать границы для всех ваших блоков или индивидуально, добавляя элемент управления цветом границы на вкладку свойств для группового блока.
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
Вы должны использовать Me.ClientRectangle вместо Me.DisplayRectangle для бодера и текста. Если вы используете старый способ, то проблема мерцания не решается, и текст группового поля не будет отображаться.