vb.net winform 中的组切换按钮
Group toggle buttons in vb.net winform
我正在为一个需要放置一些切换按钮的小应用程序制作主题。
就像在这个网站的许多地方展示的那样,我使用复选框并通过自定义 onpaint 事件更改外观来完成它,(基本上像按钮一样绘制它)。然后我意识到复选框不像单选按钮那样分组,所以我对单选按钮做了同样的事情,但即使我将其中的 2 个放在一个分组框中,我仍然可以“选中”它们;
这是最好的方法吗?
这是我用来做一些测试的示例代码:
Class MyToggleButton
Inherits ThemeControl154
Private _Checked As Boolean
Private X As Integer
Public Property Checked As Boolean
Get
Return _Checked
End Get
Set(ByVal V As Boolean)
_Checked = V
Invalidate()
End Set
End Property
Protected Overrides Sub OnClick(ByVal e As System.EventArgs)
MyBase.OnClick(e)
_Checked = Not _Checked
End Sub
Protected Overrides Sub ColorHook()
SetColor("Border", Color.FromArgb(255, 200, 200, 200))
End Sub
Protected Overrides Sub PaintHook()
Dim Border As Color
Border = Drawing.Color.FromArgb(160, GetColor("Border"))
G.SmoothingMode = SmoothingMode.AntiAlias
G.Clear(Drawing.Color.FromArgb(255, 60, 60, 60))
Dim LGBNone As LinearGradientBrush
Dim LGBOver As LinearGradientBrush
Dim LGBDown As LinearGradientBrush
If Checked Then ' use Blue-ish color
LGBNone = New LinearGradientBrush(New Point(0, 0), New Point(0, Height - 1), Color.FromArgb(120, 0, 0, 255), Color.FromArgb(255, 25, 50, 255))
LGBOver = New LinearGradientBrush(New Point(0, 0), New Point(0, Height - 1), Color.FromArgb(120, 0, 0, 255), Color.FromArgb(255, 25, 40, 255))
LGBDown = New LinearGradientBrush(New Point(0, 0), New Point(0, Height - 1), Color.FromArgb(120, 0, 0, 255), Color.FromArgb(255, 25, 30, 255))
Else ' use default colors
LGBNone = New LinearGradientBrush(New Point(0, 0), New Point(0, Height - 1), Color.FromArgb(255, 65, 65, 65), Color.FromArgb(255, 50, 50, 50))
LGBOver = New LinearGradientBrush(New Point(0, 0), New Point(0, Height - 1), Color.FromArgb(255, 65, 65, 65), Color.FromArgb(255, 40, 40, 40))
LGBDown = New LinearGradientBrush(New Point(0, 0), New Point(0, Height - 1), Color.FromArgb(255, 65, 65, 65), Color.FromArgb(255, 30, 30, 30))
End If
Dim Polygon() As Point
Dim Polygon2() As Point
Polygon = New Point() {New Point(0, 0), New Point(Width - 1, 0), New Point(Width - 1, Height - 7), New Point(Width - 2, Height - 6), New Point(Width - 3, Height - 5), New Point(Width - 4, Height - 4), New Point(Width - 5, Height - 3), New Point(Width - 6, Height - 2), New Point(Width - 7, Height - 1), New Point(0, Height - 1)}
Polygon2 = New Point() {New Point(1, 1), New Point(Width - 2, 1), New Point(Width - 2, Height - 7), New Point(Width - 8, Height - 2), New Point(1, Height - 2)}
Select Case State
Case MouseState.Down
G.FillPolygon(LGBDown, Polygon)
Case MouseState.None
G.FillPolygon(LGBNone, Polygon)
Case MouseState.Over
G.FillPolygon(LGBOver, Polygon)
End Select
G.DrawPolygon(Pens.Black, Polygon)
G.DrawPolygon(New Pen(Border), Polygon2)
DrawText(New SolidBrush(GetColor("Border")), HorizontalAlignment.Center, -2, 0)
End Sub
结束Class
是的,您可以在容器中模仿一组 RadioButton 控件的行为。只需在Parent.Controls
集合中找到相同类型的控件,并在选中当前实例时取消选中即可。
例子
将此方法添加到 MyToggleButton
class。
Private Sub InvalidateControls()
If Not IsHandleCreated OrElse Not Checked Then Return
For Each c In Parent.Controls.OfType(Of MyToggleButton)
If c IsNot Me AndAlso c.Checked Then
c.Checked = False
End If
Next
End Sub
从 Checked
的 setter 调用方法 属性:
Private _Checked As Boolean
Public Property Checked As Boolean
Get
Return _Checked
End Get
Set(ByVal V As Boolean)
_Checked = V
InvalidateControls()
Invalidate()
End Set
End Property
在 OnClick
方法中,您不应切换 Checked
属性,它是 RadioButton
而不是 CheckBox
。你应该:
Protected Overrides Sub OnClick(ByVal e As EventArgs)
MyBase.OnClick(e)
' Set the property not the variable to call the
' setter's methods.
If Not Checked Then Checked = True
End Sub
此外,完成绘图后处理图形对象也很重要。您应该在 PaintHook
方法的末尾调用 LGBNone.Dispose()
、LGBDown.Dispose()
和 LGBOver.Dispose()
。
我正在为一个需要放置一些切换按钮的小应用程序制作主题。 就像在这个网站的许多地方展示的那样,我使用复选框并通过自定义 onpaint 事件更改外观来完成它,(基本上像按钮一样绘制它)。然后我意识到复选框不像单选按钮那样分组,所以我对单选按钮做了同样的事情,但即使我将其中的 2 个放在一个分组框中,我仍然可以“选中”它们; 这是最好的方法吗? 这是我用来做一些测试的示例代码:
Class MyToggleButton
Inherits ThemeControl154
Private _Checked As Boolean
Private X As Integer
Public Property Checked As Boolean
Get
Return _Checked
End Get
Set(ByVal V As Boolean)
_Checked = V
Invalidate()
End Set
End Property
Protected Overrides Sub OnClick(ByVal e As System.EventArgs)
MyBase.OnClick(e)
_Checked = Not _Checked
End Sub
Protected Overrides Sub ColorHook()
SetColor("Border", Color.FromArgb(255, 200, 200, 200))
End Sub
Protected Overrides Sub PaintHook()
Dim Border As Color
Border = Drawing.Color.FromArgb(160, GetColor("Border"))
G.SmoothingMode = SmoothingMode.AntiAlias
G.Clear(Drawing.Color.FromArgb(255, 60, 60, 60))
Dim LGBNone As LinearGradientBrush
Dim LGBOver As LinearGradientBrush
Dim LGBDown As LinearGradientBrush
If Checked Then ' use Blue-ish color
LGBNone = New LinearGradientBrush(New Point(0, 0), New Point(0, Height - 1), Color.FromArgb(120, 0, 0, 255), Color.FromArgb(255, 25, 50, 255))
LGBOver = New LinearGradientBrush(New Point(0, 0), New Point(0, Height - 1), Color.FromArgb(120, 0, 0, 255), Color.FromArgb(255, 25, 40, 255))
LGBDown = New LinearGradientBrush(New Point(0, 0), New Point(0, Height - 1), Color.FromArgb(120, 0, 0, 255), Color.FromArgb(255, 25, 30, 255))
Else ' use default colors
LGBNone = New LinearGradientBrush(New Point(0, 0), New Point(0, Height - 1), Color.FromArgb(255, 65, 65, 65), Color.FromArgb(255, 50, 50, 50))
LGBOver = New LinearGradientBrush(New Point(0, 0), New Point(0, Height - 1), Color.FromArgb(255, 65, 65, 65), Color.FromArgb(255, 40, 40, 40))
LGBDown = New LinearGradientBrush(New Point(0, 0), New Point(0, Height - 1), Color.FromArgb(255, 65, 65, 65), Color.FromArgb(255, 30, 30, 30))
End If
Dim Polygon() As Point
Dim Polygon2() As Point
Polygon = New Point() {New Point(0, 0), New Point(Width - 1, 0), New Point(Width - 1, Height - 7), New Point(Width - 2, Height - 6), New Point(Width - 3, Height - 5), New Point(Width - 4, Height - 4), New Point(Width - 5, Height - 3), New Point(Width - 6, Height - 2), New Point(Width - 7, Height - 1), New Point(0, Height - 1)}
Polygon2 = New Point() {New Point(1, 1), New Point(Width - 2, 1), New Point(Width - 2, Height - 7), New Point(Width - 8, Height - 2), New Point(1, Height - 2)}
Select Case State
Case MouseState.Down
G.FillPolygon(LGBDown, Polygon)
Case MouseState.None
G.FillPolygon(LGBNone, Polygon)
Case MouseState.Over
G.FillPolygon(LGBOver, Polygon)
End Select
G.DrawPolygon(Pens.Black, Polygon)
G.DrawPolygon(New Pen(Border), Polygon2)
DrawText(New SolidBrush(GetColor("Border")), HorizontalAlignment.Center, -2, 0)
End Sub
结束Class
是的,您可以在容器中模仿一组 RadioButton 控件的行为。只需在Parent.Controls
集合中找到相同类型的控件,并在选中当前实例时取消选中即可。
例子
将此方法添加到 MyToggleButton
class。
Private Sub InvalidateControls()
If Not IsHandleCreated OrElse Not Checked Then Return
For Each c In Parent.Controls.OfType(Of MyToggleButton)
If c IsNot Me AndAlso c.Checked Then
c.Checked = False
End If
Next
End Sub
从 Checked
的 setter 调用方法 属性:
Private _Checked As Boolean
Public Property Checked As Boolean
Get
Return _Checked
End Get
Set(ByVal V As Boolean)
_Checked = V
InvalidateControls()
Invalidate()
End Set
End Property
在 OnClick
方法中,您不应切换 Checked
属性,它是 RadioButton
而不是 CheckBox
。你应该:
Protected Overrides Sub OnClick(ByVal e As EventArgs)
MyBase.OnClick(e)
' Set the property not the variable to call the
' setter's methods.
If Not Checked Then Checked = True
End Sub
此外,完成绘图后处理图形对象也很重要。您应该在 PaintHook
方法的末尾调用 LGBNone.Dispose()
、LGBDown.Dispose()
和 LGBOver.Dispose()
。