| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- Imports System.Windows.Markup
- <ContentProperty("Inlines")>
- Public Class MyRadioButton
- '基础
- Public Uuid As Integer = GetUuid()
- Public Event Check(sender As Object, raiseByMouse As Boolean)
- '自定义属性
- Public Property Logo As String
- Get
- Return ShapeLogo.Data.ToString
- End Get
- Set(value As String)
- ShapeLogo.Data = (New GeometryConverter).ConvertFromString(value)
- End Set
- End Property
- Private _LogoScale As Double = 1
- Public Property LogoScale() As Double
- Get
- Return _LogoScale
- End Get
- Set(value As Double)
- _LogoScale = value
- If Not IsNothing(ShapeLogo) Then ShapeLogo.RenderTransform = New ScaleTransform With {.ScaleX = LogoScale, .ScaleY = LogoScale}
- End Set
- End Property
- Private _Checked As Boolean = False '是否选中
- Public Property Checked As Boolean
- Get
- Return _Checked
- End Get
- Set(value As Boolean)
- SetChecked(value, False, True)
- End Set
- End Property
- ''' <summary>
- ''' 手动设置 Checked 属性。
- ''' </summary>
- ''' <param name="value">新的 Checked 属性。</param>
- ''' <param name="raiseByMouse">是否由用户引发。</param>
- ''' <param name="anime">是否执行动画。</param>
- Public Sub SetChecked(value As Boolean, raiseByMouse As Boolean, anime As Boolean)
- Try
- '自定义属性基础
- Dim IsChanged As Boolean = False
- If _Checked <> value Then
- _Checked = value
- IsChanged = True
- End If
- '保证只有一个单选框选中
- If Parent Is Nothing Then Return
- Dim RadioboxList As New List(Of MyRadioButton)
- Dim CheckedCount As Integer = 0
- '收集控件列表与选中个数
- For Each Control In CType(Parent, Object).Children
- If TypeOf Control Is MyRadioButton Then
- RadioboxList.Add(Control)
- If Control.Checked Then CheckedCount += 1
- End If
- Next
- '判断选中情况
- Select Case CheckedCount
- Case 0
- '没有任何单选框被选中,选择第一个
- RadioboxList(0).Checked = True
- Case Is > 1
- '选中项目多于 1 个
- If Me.Checked Then
- '如果本控件选中,则取消其他所有控件的选中
- For Each Control As MyRadioButton In RadioboxList
- If Control.Checked AndAlso Not Control.Equals(Me) Then Control.Checked = False
- Next
- Else
- '如果本控件未选中,则只保留第一个选中的控件
- Dim FirstChecked = False
- For Each Control As MyRadioButton In RadioboxList
- If Control.Checked Then
- If FirstChecked Then
- Control.Checked = False '修改 Checked 会自动触发 Change 事件,所以不用额外触发
- Else
- FirstChecked = True
- End If
- End If
- Next
- End If
- End Select
- '更改动画
- If Not IsChanged Then Return
- RefreshColor(Nothing, anime)
- '触发事件
- If Checked Then RaiseEvent Check(Me, raiseByMouse)
- RaiseCustomEvent()
- Catch ex As Exception
- Logger.Error(ex, "单选按钮勾选改变错误", LogBehavior.Toast)
- End Try
- End Sub
- Public ReadOnly Property Inlines As InlineCollection
- Get
- Return LabText.Inlines
- End Get
- End Property
- Public Property Text As String
- Get
- Return GetValue(TextProperty)
- End Get
- Set(value As String)
- SetValue(TextProperty, value)
- End Set
- End Property '内容
- Public Shared ReadOnly TextProperty As DependencyProperty = DependencyProperty.Register("Text", GetType(String), GetType(MyRadioButton), New PropertyMetadata(New PropertyChangedCallback(
- Sub(sender, e) If sender IsNot Nothing Then CType(sender, MyRadioButton).LabText.Text = e.NewValue)))
- Public Enum ColorState
- White
- Highlight
- End Enum
- Private _ColorType As ColorState = ColorState.White
- Public Property ColorType As ColorState
- Get
- Return _ColorType
- End Get
- Set(value As ColorState)
- _ColorType = value
- RefreshColor()
- End Set
- End Property '颜色类别
- '点击事件
- Public Event PreviewClick(sender As Object, e As RouteEventArgs)
- Private IsMouseDown As Boolean = False
- Private Sub Radiobox_MouseUp() Handles Me.MouseLeftButtonUp
- If Checked Then Return
- If Not IsMouseDown Then Return
- Logger.Info($"按下单选按钮:{Text}")
- IsMouseDown = False
- Dim e As New RouteEventArgs(True)
- RaiseEvent PreviewClick(Me, e)
- If e.Handled Then Return
- SetChecked(True, True, True)
- End Sub
- Private Sub Radiobox_MouseDown() Handles Me.MouseLeftButtonDown
- If Checked Then Return
- IsMouseDown = True
- RefreshColor()
- End Sub
- Private Sub Radiobox_MouseLeave() Handles Me.MouseLeave
- IsMouseDown = False
- End Sub
- '动画
- Private Const AnimationTimeOfMouseIn As Integer = 90 '鼠标指向动画长度
- Private Const AnimationTimeOfMouseOut As Integer = 150 '鼠标移出动画长度
- Private Const AnimationTimeOfCheck As Integer = 120 '勾选状态变更动画长度
- Private Sub RefreshColor(Optional obj = Nothing, Optional e = Nothing) Handles Me.MouseEnter, Me.MouseLeave, Me.Loaded
- Try
- If IsLoaded AndAlso AniControlEnabled = 0 AndAlso Not False.Equals(e) Then '防止默认属性变更触发动画,若强制不执行动画,则 e 为 False
- Select Case ColorType
- Case ColorState.White
- If Checked Then
- '勾选
- AniStart({
- AaColor(ShapeLogo, Shapes.Path.FillProperty, "ColorBrush3", AnimationTimeOfCheck),
- AaColor(LabText, TextBlock.ForegroundProperty, "ColorBrush3", AnimationTimeOfCheck)
- }, "MyRadioButton Checked " & Uuid)
- AniStart(AaColor(Me, BackgroundProperty, New MyColor(255, 255, 255) - Background, AnimationTimeOfCheck), "MyRadioButton Color " & Uuid)
- ElseIf IsMouseDown Then
- '按下
- AniStart(AaColor(Me, BackgroundProperty, New MyColor(120, Color8) - Background, 60), "MyRadioButton Color " & Uuid)
- ElseIf IsMouseOver Then
- '指向
- AniStart({
- AaColor(ShapeLogo, Shapes.Path.FillProperty, New MyColor(255, 255, 255) - ShapeLogo.Fill, AnimationTimeOfMouseIn),
- AaColor(LabText, TextBlock.ForegroundProperty, New MyColor(255, 255, 255) - LabText.Foreground, AnimationTimeOfMouseIn)
- }, "MyRadioButton Checked " & Uuid)
- AniStart(AaColor(Me, BackgroundProperty, New MyColor(50, Color8) - Background, AnimationTimeOfMouseIn), "MyRadioButton Color " & Uuid)
- Else
- '正常
- AniStart({
- AaColor(ShapeLogo, Shapes.Path.FillProperty, New MyColor(255, 255, 255) - ShapeLogo.Fill, AnimationTimeOfMouseOut),
- AaColor(LabText, TextBlock.ForegroundProperty, New MyColor(255, 255, 255) - LabText.Foreground, AnimationTimeOfMouseOut)
- }, "MyRadioButton Checked " & Uuid)
- AniStart(AaColor(Me, BackgroundProperty, ColorSemiTransparent - Background, AnimationTimeOfMouseOut), "MyRadioButton Color " & Uuid)
- End If
- Case ColorState.Highlight
- If Checked Then
- '勾选
- AniStart({
- AaColor(ShapeLogo, Shapes.Path.FillProperty, New MyColor(255, 255, 255) - ShapeLogo.Fill, AnimationTimeOfCheck),
- AaColor(LabText, TextBlock.ForegroundProperty, New MyColor(255, 255, 255) - LabText.Foreground, AnimationTimeOfCheck)
- }, "MyRadioButton Checked " & Uuid)
- AniStart(AaColor(Me, BackgroundProperty, "ColorBrush3", AnimationTimeOfCheck), "MyRadioButton Color " & Uuid)
- ElseIf IsMouseDown Then
- '按下
- AniStart(AaColor(Me, BackgroundProperty, "ColorBrush6", AnimationTimeOfMouseIn), "MyRadioButton Color " & Uuid)
- ElseIf IsMouseOver Then
- '指向
- AniStart({
- AaColor(ShapeLogo, Shapes.Path.FillProperty, "ColorBrush3", AnimationTimeOfMouseIn),
- AaColor(LabText, TextBlock.ForegroundProperty, "ColorBrush3", AnimationTimeOfMouseIn)
- }, "MyRadioButton Checked " & Uuid)
- AniStart(AaColor(Me, BackgroundProperty, "ColorBrush7", AnimationTimeOfMouseIn), "MyRadioButton Color " & Uuid)
- Else
- '正常
- AniStart({
- AaColor(ShapeLogo, Shapes.Path.FillProperty, "ColorBrush3", AnimationTimeOfMouseOut),
- AaColor(LabText, TextBlock.ForegroundProperty, "ColorBrush3", AnimationTimeOfMouseOut)
- }, "MyRadioButton Checked " & Uuid)
- AniStart(AaColor(Me, BackgroundProperty, ColorSemiTransparent - Background, AnimationTimeOfMouseOut), "MyRadioButton Color " & Uuid)
- End If
- End Select
- Else
- '不使用动画
- AniStop("MyRadioButton Checked " & Uuid)
- AniStop("MyRadioButton Color " & Uuid)
- Select Case ColorType
- Case ColorState.White
- If Checked Then
- Background = New MyColor(255, 255, 255)
- ShapeLogo.SetResourceReference(Shapes.Path.FillProperty, "ColorBrush3")
- LabText.SetResourceReference(TextBlock.ForegroundProperty, "ColorBrush3")
- Else
- Background = ColorSemiTransparent
- ShapeLogo.Fill = New MyColor(255, 255, 255)
- LabText.Foreground = New MyColor(255, 255, 255)
- End If
- Case ColorState.Highlight
- If Checked Then
- SetResourceReference(BackgroundProperty, "ColorBrush3")
- ShapeLogo.Fill = New MyColor(255, 255, 255)
- LabText.Foreground = New MyColor(255, 255, 255)
- Else
- Background = ColorSemiTransparent
- ShapeLogo.SetResourceReference(Shapes.Path.FillProperty, "ColorBrush3")
- LabText.SetResourceReference(TextBlock.ForegroundProperty, "ColorBrush3")
- End If
- End Select
- End If
- Catch ex As Exception
- Logger.Warn(ex, "刷新单选按钮颜色出错")
- End Try
- End Sub
- End Class
|