首页 > 解决方案 > vb.net winform中的组切换按钮

问题描述

我正在为一个小应用程序开发一个主题,我需要在其中放置一些切换按钮。就像在这个网站的许多地方展示的那样,我使用一个复选框来完成它,并通过一个自定义的 onpaint 事件来改变外观,(基本上就像一个按钮一样绘制它)。然后我意识到该复选框不像单选按钮那样分组,所以我对单选按钮做了同样的事情,但即使我将其中两个放在一个组框中,我仍然可以“选中”它们;这是最好的方法吗?这里是我用来做一些测试的示例代码:

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

结束类

标签: vb.netwinformsbutton

解决方案


是的,您可以模仿容器中一组 RadioButton 控件的行为。只需在集合中找到相同类型的控件,Parent.Controls并在选中当前实例时取消选中它们。

例子

将此方法添加到MyToggleButton类中。

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属性,它 aRadioButton不是 a 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

此外,完成绘图后处理图形对象也很重要。您应该在方法的末尾调用LGBNone.Dispose(),LGBDown.Dispose()和。LGBOver.Dispose()PaintHook


推荐阅读