【问题标题】:Group toggle buttons in vb.net winformvb.net winform中的组切换按钮
【发布时间】:2021-08-29 07:03:07
【问题描述】:

我正在为一个小应用程序设计一个主题,我需要在其中放置一些切换按钮。 就像在这个网站的许多地方展示的那样,我使用一个复选框来完成它,并通过一个自定义的 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

结束类

【问题讨论】:

  • 这不是 RadioButton 的正常行为。因此,它必须与您的代码有关(您没有包括在内)。无论如何,我想你会喜欢this answer。代码在 C# 中,但可以轻松翻译(或按原样编译成 DLL)。
  • 只要RadioButtons 属于同一个父级,它们就会自动切换。如果每个RadioButton 有不同的父级,则不会切换。
  • 但是请注意,切换开关通常替代 CheckBox,而不是 RadioButton。因此,切换会影响其他人的状态可能是用户的意外行为。您不喜欢广为人知的 RadioButton 的哪些方面?
  • 基本上单选按钮可以实现我的目标,但我更喜欢按钮外观。
  • @Damien 你试过RadioButton.Appearance 属性了吗?例如,RadioButton1.Appearance = Appearance.Button.

标签: vb.net winforms button


【解决方案1】:

是的,您可以模仿容器中一组 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 属性,它是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()

【讨论】:

  • 这正是我想要的!!谢谢。
猜你喜欢
  • 2012-09-08
  • 2011-09-11
  • 1970-01-01
  • 2014-12-04
  • 1970-01-01
  • 1970-01-01
  • 2012-03-17
  • 2014-09-19
  • 2023-04-02
相关资源
最近更新 更多