MyComboBox.vb 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. Public Class MyComboBox
  2. Inherits ComboBox
  3. Public Event TextChanged(sender As Object, e As TextChangedEventArgs)
  4. '基础
  5. Public Uuid As Integer = GetUuid()
  6. Private TextBox As MyTextBox
  7. Public Property HintText As String = ""
  8. Public Overrides Sub OnApplyTemplate()
  9. MyBase.OnApplyTemplate()
  10. If Not IsEditable Then Return
  11. Try
  12. TextBox = Template.FindName("PART_EditableTextBox", Me)
  13. TextBox.AddHandler(LostFocusEvent, New RoutedEventHandler(AddressOf RefreshColor))
  14. TextBox.ChangedEventList.Add(New RoutedEventHandler(Sub(sender, e) RaiseEvent TextChanged(sender, e)))
  15. TextBox.Tag = Tag '有时需要用文本框的 Tag 来写入设置
  16. If Text = "" Then
  17. TextBox.Text = _Text
  18. Else
  19. RaiseEvent TextChanged(Me, Nothing)
  20. End If
  21. If HintText.Length > 0 Then TextBox.HintText = HintText
  22. Catch ex As Exception
  23. Log(ex, "初始化可编辑文本框失败(" & If(Name, "") & ")", LogLevel.Feedback)
  24. End Try
  25. End Sub
  26. Private _Text As String = SelectedItem
  27. Public Shadows Property Text As String
  28. Get
  29. If IsEditable Then
  30. If TextBox Is Nothing Then
  31. Return If(_Text, "")
  32. Else
  33. Return If(TextBox.Text, "")
  34. End If
  35. Else
  36. Return If(SelectedItem, "").ToString
  37. End If
  38. End Get
  39. Set(value As String)
  40. If IsEditable Then
  41. If IsNothing(TextBox) Then
  42. _Text = value
  43. Else
  44. TextBox.Text = value
  45. End If
  46. Else
  47. Throw New NotSupportedException("该 ComboBox 不支持修改文本。")
  48. End If
  49. End Set
  50. End Property
  51. '鼠标按下接口
  52. Private IsMouseDown As Boolean = False
  53. Private Sub MyComboBox_PreviewMouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseLeftButtonDown
  54. IsMouseDown = True
  55. End Sub
  56. Private Sub MyComboBox_PreviewMouseLeftButtonUp(sender As Object, e As EventArgs) Handles Me.PreviewMouseLeftButtonUp, Me.MouseLeave
  57. IsMouseDown = False
  58. End Sub
  59. '指向动画
  60. Public Sub RefreshColor() Handles Me.IsEnabledChanged, Me.MouseEnter, Me.MouseLeave, Me.PreviewMouseLeftButtonDown, Me.PreviewMouseLeftButtonUp, Me.GotKeyboardFocus
  61. '判断当前颜色
  62. Dim ForeColorName As String
  63. Dim BackColorName As String
  64. Dim Time As Integer
  65. If IsEnabled Then
  66. If IsMouseDown OrElse IsDropDownOpen OrElse (IsEditable AndAlso Template.FindName("PART_EditableTextBox", Me).IsFocused) Then
  67. ForeColorName = "ColorBrush3"
  68. BackColorName = "ColorBrush7"
  69. Time = 10
  70. ElseIf IsMouseOver Then
  71. ForeColorName = "ColorBrush4"
  72. BackColorName = "ColorBrush7"
  73. Time = 100
  74. Else
  75. ForeColorName = "ColorBrushBg0"
  76. BackColorName = "ColorBrushHalfWhite"
  77. Time = 100
  78. End If
  79. Else
  80. ForeColorName = "ColorBrushGray5"
  81. BackColorName = "ColorBrushGray6"
  82. Time = 200
  83. End If
  84. '触发颜色动画
  85. If IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画
  86. '有动画
  87. AniStart({
  88. AaColor(Me, ForegroundProperty, ForeColorName, Time),
  89. AaColor(Me, BackgroundProperty, BackColorName, Time)
  90. }, "MyComboBox Color " & Uuid)
  91. Else
  92. '无动画
  93. AniStop("MyComboBox Color " & Uuid)
  94. SetResourceReference(ForegroundProperty, ForeColorName)
  95. SetResourceReference(BackgroundProperty, BackColorName)
  96. End If
  97. End Sub
  98. Private RealWidth As Double '由于下拉框 Popup 宽度与 Width 一致,故不能为 NaN(Auto)
  99. Private Sub MyComboBox_DropDownOpened(sender As Object, e As EventArgs) Handles Me.DropDownOpened
  100. RealWidth = Width
  101. Width = ActualWidth
  102. Try
  103. CType(Template.FindName("PanPopup", Me), Grid).Opacity = FrmMain.Opacity
  104. Catch ex As Exception
  105. Log(ex, "设置下拉框透明度失败", LogLevel.Feedback)
  106. End Try
  107. End Sub
  108. Private Sub MyComboBox_DropDownClosed(sender As Object, e As EventArgs) Handles Me.DropDownClosed
  109. Width = RealWidth
  110. End Sub
  111. '修复 WPF Bug:下拉框文本修改后,依然误认为还选择着此前的选项,导致再次点击该选项时内容不变
  112. Private IsTextChanging As Boolean = False
  113. Private Sub MyComboBox_TextChanged(sender As Object, e As TextChangedEventArgs) Handles Me.TextChanged
  114. If IsTextChanging OrElse Not IsEditable Then Return
  115. If SelectedItem Is Nothing OrElse Text = SelectedItem.ToString Then Return
  116. Dim RawText As String = Text
  117. Dim RawSelectionStart As Integer = TextBox.SelectionStart
  118. IsTextChanging = True
  119. SelectedItem = Nothing
  120. Text = RawText
  121. TextBox.SelectionStart = RawSelectionStart
  122. IsTextChanging = False
  123. End Sub
  124. Public ReadOnly Property ContentPresenter As ContentPresenter
  125. Get
  126. Return Template.FindName("PART_Content", Me)
  127. End Get
  128. End Property
  129. Private Sub MyComboBox_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles Me.SelectionChanged
  130. If IsLoaded AndAlso AniControlEnabled = 0 Then RaiseCustomEvent()
  131. End Sub
  132. End Class