| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- Imports System.Windows.Markup
- <ContentProperty("Inlines")>
- Public Class MyCheckBox
- Implements ISettingControl
- '基础
- Public Uuid As Integer = GetUuid()
- ''' <summary>
- ''' 复选框勾选状态改变。
- ''' </summary>
- ''' <param name="user">是否为用户手动改变的勾选状态。</param>
- Public Event Change(sender As Object, user As Boolean)
- Public Event PreviewChange(sender As Object, e As RouteEventArgs)
- '自定义属性
- Public Property Checked As Boolean
- Get
- Return GetValue(CheckedProperty)
- End Get
- Set(value As Boolean)
- SetChecked(value, False)
- End Set
- End Property
- Public Shared ReadOnly CheckedProperty As DependencyProperty =
- DependencyProperty.Register("Checked", GetType(Boolean), GetType(MyCheckBox), New PropertyMetadata(False,
- Sub(d As MyCheckBox, e As DependencyPropertyChangedEventArgs)
- '在使用 XAML 设置 Checked 属性时,不会触发 Checked_Set 方法,所以需要在这里手动触发 UI 改变
- If Not d.IsLoaded Then d.SyncUI()
- End Sub))
- Private Const AnimationTimeOfCheck As Integer = 150 '勾选状态变更动画长度
- ''' <summary>
- ''' 手动设置 Checked 属性。
- ''' </summary>
- ''' <param name="value">新的 Checked 属性。</param>
- ''' <param name="user">是否由用户引发。</param>
- Public Sub SetChecked(value As Boolean, user As Boolean)
- Try
- If value = Checked Then Return
- 'Preview 事件
- If value AndAlso user Then
- Dim e = New RouteEventArgs(user)
- RaiseEvent PreviewChange(Me, e)
- If e.Handled Then
- MouseDowned = True
- Checkbox_MouseLeave()
- MouseDowned = False
- Return
- End If
- End If
- SetValue(CheckedProperty, value)
- If IsLoaded Then RaiseEvent Change(Me, user)
- '更改动画
- SyncUI()
- RaiseCustomEvent()
- Catch ex As Exception
- Logger.Warn(ex, "设置 Checked 失败")
- End Try
- End Sub
- Private Sub SyncUI()
- If AniControlEnabled = 0 AndAlso IsLoaded Then '防止默认属性变更触发动画
- AllowMouseDown = False
- If Checked Then
- '由无变有
- AniStart({
- AaScale(ShapeBorder, 12 - ShapeBorder.Width, AnimationTimeOfCheck, , New AniEaseOutFluent, , True),
- AaScaleTransform(ShapeCheck, 1 - CType(ShapeCheck.RenderTransform, ScaleTransform).ScaleX, AnimationTimeOfCheck * 2, AnimationTimeOfCheck * 0.7, New AniEaseOutBack(AniEasePower.Weak)),
- AaScale(ShapeBorder, 6, AnimationTimeOfCheck * 2, AnimationTimeOfCheck * 0.7, New AniEaseOutBack, , True)
- }, "MyCheckBox Scale " & Uuid)
- AniStart({
- AaColor(ShapeBorder, Border.BorderBrushProperty, If(IsEnabled, If(IsMouseOver, "ColorBrush3", "ColorBrush2"), "ColorBrushGray5"), AnimationTimeOfCheck)
- }, "MyCheckBox BorderColor " & Uuid)
- AniStart({
- AaCode(Sub() AllowMouseDown = True, AnimationTimeOfCheck * 2)
- }, "MyCheckBox AllowMouseDown " & Uuid)
- Else
- '由有变无
- AniStart({
- AaScale(ShapeBorder, 12 - ShapeBorder.Width, AnimationTimeOfCheck, , New AniEaseOutFluent, , True),
- AaScaleTransform(ShapeCheck, -CType(ShapeCheck.RenderTransform, ScaleTransform).ScaleX, AnimationTimeOfCheck * 0.9, , New AniEaseInFluent(AniEasePower.Weak)),
- AaScale(ShapeBorder, 6, AnimationTimeOfCheck * 2, AnimationTimeOfCheck * 0.7, New AniEaseOutBack, , True)
- }, "MyCheckBox Scale " & Uuid)
- AniStart({
- AaColor(ShapeBorder, Border.BorderBrushProperty, If(IsEnabled, If(IsMouseOver, "ColorBrush3", "ColorBrush1"), "ColorBrushGray5"), AnimationTimeOfCheck)
- }, "MyCheckBox BorderColor " & Uuid)
- AniStart({
- AaCode(Sub() AllowMouseDown = True, AnimationTimeOfCheck * 2)
- }, "MyCheckBox AllowMouseDown " & Uuid)
- End If
- Else
- '不使用动画
- AniStop("MyCheckBox Scale " & Uuid)
- AniStop("MyCheckBox BorderColor " & Uuid)
- AniStop("MyCheckBox AllowMouseDown " & Uuid)
- If Checked Then
- CType(ShapeCheck.RenderTransform, ScaleTransform).ScaleX = 1
- CType(ShapeCheck.RenderTransform, ScaleTransform).ScaleY = 1
- ShapeBorder.SetResourceReference(Border.BorderBrushProperty, If(IsEnabled, "ColorBrush2", "ColorBrushGray5"))
- Else
- CType(ShapeCheck.RenderTransform, ScaleTransform).ScaleX = 0
- CType(ShapeCheck.RenderTransform, ScaleTransform).ScaleY = 0
- ShapeBorder.SetResourceReference(Border.BorderBrushProperty, If(IsEnabled, "ColorBrush1", "ColorBrushGray5"))
- End If
- End If
- 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(MyCheckBox), New PropertyMetadata(New PropertyChangedCallback(
- Sub(sender As DependencyObject, e As DependencyPropertyChangedEventArgs)
- If Not IsNothing(sender) Then CType(sender, MyCheckBox).LabText.Text = e.NewValue
- End Sub)))
- '点击事件
- Private MouseDowned As Boolean = False
- Private AllowMouseDown As Boolean = True
- Private Sub Checkbox_MouseUp() Handles Me.MouseLeftButtonUp
- If Not MouseDowned Then Return
- Logger.Info($"按下复选框({(Not Checked)}):{Text}")
- MouseDowned = False
- SetChecked(Not Checked, True)
- AniStart(AaColor(ShapeBorder, Border.BackgroundProperty, "ColorBrushHalfWhite", 100), "MyCheckBox Background " & Uuid)
- End Sub
- Private Sub Checkbox_MouseDown() Handles Me.MouseLeftButtonDown
- If Not AllowMouseDown Then Return
- MouseDowned = True
- Focus()
- AniStart(AaColor(ShapeBorder, Border.BackgroundProperty, "ColorBrushBg1", 100), "MyCheckBox Background " & Uuid)
- If Checked Then
- AniStart({
- AaScale(ShapeBorder, 16.5 - ShapeBorder.Width, 1000, , New AniEaseOutFluent(AniEasePower.Strong), Absolute:=True),
- AaScaleTransform(ShapeCheck, 0.9 - CType(ShapeCheck.RenderTransform, ScaleTransform).ScaleX, 1000, , New AniEaseOutFluent(AniEasePower.Strong))
- }, "MyCheckBox Scale " & Uuid)
- Else
- AniStart(AaScale(ShapeBorder, 16.5 - ShapeBorder.Width, 1000, , New AniEaseOutFluent(AniEasePower.Strong), Absolute:=True), "MyCheckBox Scale " & Uuid)
- End If
- End Sub
- Private Sub Checkbox_MouseLeave() Handles Me.MouseLeave
- If Not MouseDowned Then Return
- MouseDowned = False
- AniStart(AaColor(ShapeBorder, Border.BackgroundProperty, "ColorBrushHalfWhite", 100), "MyCheckBox Background " & Uuid)
- If Checked Then
- AniStart({
- AaScale(ShapeBorder, 18 - ShapeBorder.Width, 400, , New AniEaseOutFluent(AniEasePower.Strong), Absolute:=True),
- AaScaleTransform(ShapeCheck, 1 - CType(ShapeCheck.RenderTransform, ScaleTransform).ScaleX, 500, , New AniEaseOutFluent(AniEasePower.Strong))
- }, "MyCheckBox Scale " & Uuid)
- Else
- AniStart(AaScale(ShapeBorder, 18 - ShapeBorder.Width, 400, , New AniEaseOutFluent(AniEasePower.Strong), Absolute:=True), "MyCheckBox Scale " & Uuid)
- End If
- End Sub
- '指向动画
- Private Const AnimationTimeOfMouseIn As Integer = 100
- Private Const AnimationTimeOfMouseOut As Integer = 200
- Private Sub Checkbox_IsEnabledChanged() Handles Me.IsEnabledChanged
- If IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画
- '有动画
- If IsEnabled Then
- '可用
- Checkbox_MouseLeaveAnimation()
- Else
- '不可用
- AniStart({
- AaColor(ShapeBorder, Border.BorderBrushProperty, ColorGray5 - ShapeBorder.BorderBrush, AnimationTimeOfMouseOut)
- }, "MyCheckBox BorderColor " & Uuid)
- AniStart({
- AaColor(LabText, TextBlock.ForegroundProperty, ColorGray5 - LabText.Foreground, AnimationTimeOfMouseOut)
- }, "MyCheckBox TextColor " & Uuid)
- End If
- Else
- '无动画
- AniStop("MyCheckBox TextColor " & Uuid)
- AniStop("MyCheckBox BorderColor " & Uuid)
- LabText.SetResourceReference(TextBlock.ForegroundProperty, If(Me.IsEnabled, "ColorBrush1", "ColorBrushGray5"))
- ShapeBorder.SetResourceReference(Border.BorderBrushProperty, If(Me.IsEnabled, If(Checked, "ColorBrush2", "ColorBrush1"), "ColorBrushGray5"))
- End If
- End Sub
- Private Sub Checkbox_MouseEnterAnimation() Handles Me.MouseEnter
- AniStart({
- AaColor(LabText, TextBlock.ForegroundProperty, "ColorBrush3", AnimationTimeOfMouseIn)
- }, "MyCheckBox TextColor " & Uuid)
- AniStart({
- AaColor(ShapeBorder, Border.BorderBrushProperty, "ColorBrush3", AnimationTimeOfMouseIn)
- }, "MyCheckBox BorderColor " & Uuid)
- End Sub
- Private Sub Checkbox_MouseLeaveAnimation() Handles Me.MouseLeave
- If Not IsEnabled Then Return 'MouseLeave 比 IsEnabledChanged 后执行,所以如果自定义事件修改了 IsEnabled,将导致显示错误
- AniStart({
- AaColor(LabText, TextBlock.ForegroundProperty, If(Me.IsEnabled, "ColorBrush1", "ColorBrushGray5"), AnimationTimeOfMouseOut)
- }, "MyCheckBox TextColor " & Uuid)
- AniStart({
- AaColor(ShapeBorder, Border.BorderBrushProperty, If(Me.IsEnabled, If(Checked, "ColorBrush2", "ColorBrush1"), "ColorBrushGray5"), AnimationTimeOfMouseOut)
- }, "MyCheckBox BorderColor " & Uuid)
- End Sub
- #Region "设置"
- Private Sub RefreshSetting(NewValue As String) Implements ISettingControl.RefreshSetting
- Checked = Boolean.Parse(NewValue)
- End Sub
- Private Function GetCurrentSetting() As String Implements ISettingControl.GetCurrentSetting
- Return Checked.ToString
- End Function
- Private Sub SaveSetting() Handles Me.Change
- SettingService.SaveSetting(Me)
- End Sub
- #End Region
- End Class
|