MyCheckBox.xaml.vb 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. Public Class MyCheckBox
  2. '基础
  3. Public Uuid As Integer = GetUuid()
  4. ''' <summary>
  5. ''' 复选框勾选状态改变。
  6. ''' </summary>
  7. ''' <param name="user">是否为用户手动改变的勾选状态。</param>
  8. Public Event Change(sender As Object, user As Boolean)
  9. Public Event PreviewChange(sender As Object, e As RouteEventArgs)
  10. Public Sub RaiseChange()
  11. RaiseEvent Change(Me, False)
  12. End Sub '使外部程序引发本控件的 Change 事件
  13. '自定义属性
  14. Private _Checked As Boolean = False '是否选中
  15. Public Property Checked As Boolean
  16. Get
  17. Return _Checked
  18. End Get
  19. Set(value As Boolean)
  20. SetChecked(value, False, True)
  21. End Set
  22. End Property
  23. Private Const AnimationTimeOfCheck As Integer = 150 '勾选状态变更动画长度
  24. ''' <summary>
  25. ''' 手动设置 Checked 属性。
  26. ''' </summary>
  27. ''' <param name="value">新的 Checked 属性。</param>
  28. ''' <param name="user">是否由用户引发。</param>
  29. ''' <param name="anime">是否执行动画。</param>
  30. Public Sub SetChecked(value As Boolean, user As Boolean, anime As Boolean)
  31. Try
  32. If value = _Checked Then Exit Sub
  33. 'Preview 事件
  34. If value AndAlso user Then
  35. Dim e = New RouteEventArgs(user)
  36. RaiseEvent PreviewChange(Me, e)
  37. If e.Handled Then
  38. MouseDowned = True
  39. Checkbox_MouseLeave()
  40. MouseDowned = False
  41. Exit Sub
  42. End If
  43. End If
  44. _Checked = value
  45. If IsLoaded Then RaiseEvent Change(Me, user)
  46. '更改动画
  47. If IsLoaded AndAlso AniControlEnabled = 0 AndAlso anime Then '防止默认属性变更触发动画
  48. AllowMouseDown = False
  49. If Checked Then
  50. '由无变有
  51. AniStart({
  52. AaScale(ShapeBorder, 12 - ShapeBorder.Width, AnimationTimeOfCheck, , New AniEaseOutFluent, , True),
  53. AaScaleTransform(ShapeCheck, 1 - CType(ShapeCheck.RenderTransform, ScaleTransform).ScaleX, AnimationTimeOfCheck * 2, AnimationTimeOfCheck * 0.7, New AniEaseOutBack(AniEasePower.Weak)),
  54. AaScale(ShapeBorder, 6, AnimationTimeOfCheck * 2, AnimationTimeOfCheck * 0.7, New AniEaseOutBack, , True)
  55. }, "MyCheckBox Scale " & Uuid)
  56. AniStart({
  57. AaColor(ShapeBorder, Border.BorderBrushProperty, If(IsEnabled, If(IsMouseOver, "ColorBrush3", "ColorBrush2"), "ColorBrushGray4"), AnimationTimeOfCheck)
  58. }, "MyCheckBox BorderColor " & Uuid)
  59. AniStart({
  60. AaCode(Sub() AllowMouseDown = True, AnimationTimeOfCheck * 2)
  61. }, "MyCheckBox AllowMouseDown " & Uuid)
  62. Else
  63. '由有变无
  64. AniStart({
  65. AaScale(ShapeBorder, 12 - ShapeBorder.Width, AnimationTimeOfCheck, , New AniEaseOutFluent, , True),
  66. AaScaleTransform(ShapeCheck, -CType(ShapeCheck.RenderTransform, ScaleTransform).ScaleX, AnimationTimeOfCheck * 0.9, , New AniEaseInFluent(AniEasePower.Weak)),
  67. AaScale(ShapeBorder, 6, AnimationTimeOfCheck * 2, AnimationTimeOfCheck * 0.7, New AniEaseOutBack, , True)
  68. }, "MyCheckBox Scale " & Uuid)
  69. AniStart({
  70. AaColor(ShapeBorder, Border.BorderBrushProperty, If(IsEnabled, If(IsMouseOver, "ColorBrush3", "ColorBrush1"), "ColorBrushGray4"), AnimationTimeOfCheck)
  71. }, "MyCheckBox BorderColor " & Uuid)
  72. AniStart({
  73. AaCode(Sub() AllowMouseDown = True, AnimationTimeOfCheck * 2)
  74. }, "MyCheckBox AllowMouseDown " & Uuid)
  75. End If
  76. Else
  77. '不使用动画
  78. AniStop("MyCheckBox Scale " & Uuid)
  79. AniStop("MyCheckBox BorderColor " & Uuid)
  80. AniStop("MyCheckBox AllowMouseDown " & Uuid)
  81. If Checked Then
  82. CType(ShapeCheck.RenderTransform, ScaleTransform).ScaleX = 1
  83. CType(ShapeCheck.RenderTransform, ScaleTransform).ScaleY = 1
  84. ShapeBorder.SetResourceReference(Border.BorderBrushProperty, If(IsEnabled, "ColorBrush2", "ColorBrushGray4"))
  85. Else
  86. CType(ShapeCheck.RenderTransform, ScaleTransform).ScaleX = 0
  87. CType(ShapeCheck.RenderTransform, ScaleTransform).ScaleY = 0
  88. ShapeBorder.SetResourceReference(Border.BorderBrushProperty, If(IsEnabled, "ColorBrush1", "ColorBrushGray4"))
  89. End If
  90. End If
  91. Catch ex As Exception
  92. Log(ex, "设置 Checked 失败")
  93. End Try
  94. End Sub
  95. Public Property Text As String
  96. Get
  97. Return GetValue(TextProperty)
  98. End Get
  99. Set(value As String)
  100. SetValue(TextProperty, value)
  101. End Set
  102. End Property '内容
  103. Public Shared ReadOnly TextProperty As DependencyProperty = DependencyProperty.Register("Text", GetType(String), GetType(MyCheckbox), New PropertyMetadata(New PropertyChangedCallback(
  104. Sub(sender As DependencyObject, e As DependencyPropertyChangedEventArgs)
  105. If Not IsNothing(sender) Then CType(sender, MyCheckbox).LabText.Text = e.NewValue
  106. End Sub)))
  107. '点击事件
  108. Private MouseDowned As Boolean = False
  109. Private AllowMouseDown As Boolean = True
  110. Private Sub Checkbox_MouseUp() Handles Me.MouseLeftButtonUp
  111. If Not MouseDowned Then Exit Sub
  112. Log("[Control] 按下复选框(" & (Not Checked).ToString & "):" & Text)
  113. MouseDowned = False
  114. SetChecked(Not Checked, True, True)
  115. AniStart(AaColor(ShapeBorder, Border.BackgroundProperty, "ColorBrushHalfWhite", 100), "MyCheckBox Background " & Uuid)
  116. End Sub
  117. Private Sub Checkbox_MouseDown() Handles Me.MouseLeftButtonDown
  118. If Not AllowMouseDown Then Exit Sub
  119. MouseDowned = True
  120. Focus()
  121. AniStart(AaColor(ShapeBorder, Border.BackgroundProperty, "ColorBrush9", 100), "MyCheckBox Background " & Uuid)
  122. If Checked Then
  123. AniStart({
  124. AaScale(ShapeBorder, 16.5 - ShapeBorder.Width, 1000, , New AniEaseOutFluent(AniEasePower.Strong), Absolute:=True),
  125. AaScaleTransform(ShapeCheck, 0.9 - CType(ShapeCheck.RenderTransform, ScaleTransform).ScaleX, 1000, , New AniEaseOutFluent(AniEasePower.Strong))
  126. }, "MyCheckBox Scale " & Uuid)
  127. Else
  128. AniStart(AaScale(ShapeBorder, 16.5 - ShapeBorder.Width, 1000, , New AniEaseOutFluent(AniEasePower.Strong), Absolute:=True), "MyCheckBox Scale " & Uuid)
  129. End If
  130. End Sub
  131. Private Sub Checkbox_MouseLeave() Handles Me.MouseLeave
  132. If Not MouseDowned Then Exit Sub
  133. MouseDowned = False
  134. AniStart(AaColor(ShapeBorder, Border.BackgroundProperty, "ColorBrushHalfWhite", 100), "MyCheckBox Background " & Uuid)
  135. If Checked Then
  136. AniStart({
  137. AaScale(ShapeBorder, 18 - ShapeBorder.Width, 400, , New AniEaseOutFluent(AniEasePower.Strong), Absolute:=True),
  138. AaScaleTransform(ShapeCheck, 1 - CType(ShapeCheck.RenderTransform, ScaleTransform).ScaleX, 500, , New AniEaseOutFluent(AniEasePower.Strong))
  139. }, "MyCheckBox Scale " & Uuid)
  140. Else
  141. AniStart(AaScale(ShapeBorder, 18 - ShapeBorder.Width, 400, , New AniEaseOutFluent(AniEasePower.Strong), Absolute:=True), "MyCheckBox Scale " & Uuid)
  142. End If
  143. End Sub
  144. '指向动画
  145. Private Const AnimationTimeOfMouseIn As Integer = 100
  146. Private Const AnimationTimeOfMouseOut As Integer = 200
  147. Private Sub Checkbox_IsEnabledChanged() Handles Me.IsEnabledChanged
  148. If IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画
  149. '有动画
  150. If IsEnabled Then
  151. '可用
  152. Checkbox_MouseLeaveAnimation()
  153. Else
  154. '不可用
  155. AniStart({
  156. AaColor(ShapeBorder, Border.BorderBrushProperty, ColorGray4 - ShapeBorder.BorderBrush, AnimationTimeOfMouseOut)
  157. }, "MyCheckBox BorderColor " & Uuid)
  158. AniStart({
  159. AaColor(LabText, TextBlock.ForegroundProperty, ColorGray4 - LabText.Foreground, AnimationTimeOfMouseOut)
  160. }, "MyCheckBox TextColor " & Uuid)
  161. End If
  162. Else
  163. '无动画
  164. AniStop("MyCheckBox TextColor " & Uuid)
  165. AniStop("MyCheckBox BorderColor " & Uuid)
  166. LabText.SetResourceReference(TextBlock.ForegroundProperty, If(Me.IsEnabled, "ColorBrush1", "ColorBrushGray4"))
  167. ShapeBorder.SetResourceReference(Border.BorderBrushProperty, If(Me.IsEnabled, If(Checked, "ColorBrush2", "ColorBrush1"), "ColorBrushGray4"))
  168. End If
  169. End Sub
  170. Private Sub Checkbox_MouseEnterAnimation() Handles Me.MouseEnter
  171. AniStart({
  172. AaColor(LabText, TextBlock.ForegroundProperty, "ColorBrush3", AnimationTimeOfMouseIn)
  173. }, "MyCheckBox TextColor " & Uuid)
  174. AniStart({
  175. AaColor(ShapeBorder, Border.BorderBrushProperty, "ColorBrush3", AnimationTimeOfMouseIn)
  176. }, "MyCheckBox BorderColor " & Uuid)
  177. End Sub
  178. Private Sub Checkbox_MouseLeaveAnimation() Handles Me.MouseLeave
  179. If Not IsEnabled Then Exit Sub 'MouseLeave 比 IsEnabledChanged 后执行,所以如果自定义事件修改了 IsEnabled,将导致显示错误
  180. AniStart({
  181. AaColor(LabText, TextBlock.ForegroundProperty, If(Me.IsEnabled, "ColorBrush1", "ColorBrushGray4"), AnimationTimeOfMouseOut)
  182. }, "MyCheckBox TextColor " & Uuid)
  183. AniStart({
  184. AaColor(ShapeBorder, Border.BorderBrushProperty, If(Me.IsEnabled, If(Checked, "ColorBrush2", "ColorBrush1"), "ColorBrushGray4"), AnimationTimeOfMouseOut)
  185. }, "MyCheckBox BorderColor " & Uuid)
  186. End Sub
  187. End Class