Files
PCL-ISE/Plain Craft Launcher 2/Controls/MyTextBox.vb
T
2022-07-27 18:48:13 +08:00

278 lines
11 KiB
VB.net
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Public Class MyTextBox
Inherits TextBox
'自定义属性
Public Property HasAnimation As Boolean = True
Public Property ShowValidateResult As Boolean = True
'额外控件初始化
Private _labWrong As TextBlock = Nothing
Private ReadOnly Property labWrong As TextBlock
Get
If Template Is Nothing Then Return Nothing
If _labWrong Is Nothing Then _labWrong = Template.FindName("labWrong", Me)
Return _labWrong
End Get
End Property
Private _labHint As TextBlock = Nothing
Private ReadOnly Property labHint As TextBlock
Get
If Template Is Nothing Then Return Nothing
If _labHint Is Nothing Then _labHint = Template.FindName("labHint", Me)
Return _labHint
End Get
End Property
Public Overrides Sub OnApplyTemplate()
MyBase.OnApplyTemplate()
If HintText = "" OrElse labHint.Text <> "" Then Exit Sub
labHint.Text = If(Text = "", HintText, "")
End Sub
'事件
Public Uuid As Integer = GetUuid()
Public Shared Event ValidateChanged(sender As Object, e As EventArgs)
Public ChangedEventList As New List(Of RoutedEventHandler)
Public Custom Event ValidatedTextChanged As RoutedEventHandler
AddHandler(value As RoutedEventHandler)
ChangedEventList.Add(value)
End AddHandler
RemoveHandler(value As RoutedEventHandler)
ChangedEventList.Remove(value)
End RemoveHandler
RaiseEvent(sender As Object, e As TextChangedEventArgs)
For Each handler As RoutedEventHandler In ChangedEventList
If Not IsNothing(handler) Then handler.Invoke(sender, e)
Next
End RaiseEvent
End Event
'输入验证
''' <summary>
''' 输入验证结果。若为空字符串则无错误,否则为第一个错误原因。
''' </summary>
Public Property ValidateResult As String
Get
Return GetValue(ValidateResultProperty)
End Get
Set(value As String)
SetValue(ValidateResultProperty, value)
End Set
End Property
Public Shared ReadOnly ValidateResultProperty As DependencyProperty = DependencyProperty.Register("ValidateResult", GetType(String), GetType(MyTextBox), New PropertyMetadata(""))
''' <summary>
''' 输入验证的规则。
''' </summary>
Public Property ValidateRules As ObjectModel.Collection(Of Validate)
Get
Return _ValidateRules
End Get
Set(Value As ObjectModel.Collection(Of Validate))
_ValidateRules = Value
Validate()
End Set
End Property
Private _ValidateRules As New ObjectModel.Collection(Of Validate)
''' <summary>
''' 进行输入验证。
''' </summary>
Public Sub Validate() Handles Me.Loaded
'执行输入验证
ValidateResult = ""
For Each ValidateRule As Validate In ValidateRules
ValidateResult = ValidateRule.Validate(Text)
If IsNothing(ValidateResult) OrElse Not ValidateResult = "" Then Exit For
Next
Dim NewResult As Integer = If(ValidateResult = "", 0, 1)
'根据结果改变样式
If ShownValidateResult <> NewResult Then
If IsLoaded AndAlso labWrong IsNot Nothing Then
ChangeValidateResult(ValidateResult = "", True)
Else
RunInNewThread(Sub()
Thread.Sleep(30)
RunInUi(Sub() ChangeValidateResult(NewResult, False))
End Sub, "DelayedValidate Change")
End If
End If
'更新错误信息
If ShowValidateResult AndAlso Not ValidateResult = "" Then
If IsLoaded AndAlso labWrong IsNot Nothing Then
labWrong.Text = ValidateResult
Else
RunInNewThread(Sub()
Dim IsFinished As Boolean = False
Do Until IsFinished
Thread.Sleep(20)
RunInUiWait(Sub()
If labWrong IsNot Nothing Then
labWrong.Text = ValidateResult
IsFinished = True
End If
If Not IsLoaded Then IsFinished = True
End Sub)
Loop
End Sub, "DelayedValidate Text")
End If
End If
End Sub
Private ShownValidateResult As Integer = -1
Private Sub ChangeValidateResult(NewResult As Boolean, IsLoaded As Boolean)
If IsLoaded AndAlso AniControlEnabled = 0 AndAlso IsTextChanged AndAlso labWrong IsNot Nothing Then
If NewResult Then
'变为正确
ShownValidateResult = 0
AniStart({
AaOpacity(labWrong, -labWrong.Opacity, 150),
AaHeight(labWrong, -labWrong.Height, 150,, New AniEaseOutFluent),
AaCode(Sub() labWrong.Visibility = Visibility.Collapsed,, True)
}, "MyTextBox Validate " & Uuid)
ElseIf ShowValidateResult Then
'变为错误
ShownValidateResult = 1
labWrong.Visibility = Visibility.Visible
AniStart({
AaOpacity(labWrong, 1 - labWrong.Opacity, 170),
AaHeight(labWrong, 21 - labWrong.Height, 300,, New AniEaseOutBack(AniEasePower.Weak))
}, "MyTextBox Validate " & Uuid)
Else
'变为错误,但不显示文本
ShownValidateResult = 2
End If
Else
ShownValidateResult = 3
'AniStop("MyTextBox Validate " & Uuid)
'If NewResult Then
' '变为正确
' labWrong.Opacity = 0
' labWrong.Height = 0
' labWrong.Visibility = Visibility.Collapsed
'Else
' '变为错误
' labWrong.Visibility = Visibility.Visible
' labWrong.Text = ValidateResult
' labWrong.Opacity = 1
' labWrong.Height = 20.5
'End If
'Dim OriginalEnabled As Integer = AniControlEnabled
'AniControlEnabled += 1
'RefreshColor()
'AniControlEnabled = OriginalEnabled
End If
RefreshColor()
RaiseEvent ValidateChanged(Me, New EventArgs)
End Sub
'提示文本
''' <summary>
''' 是否已经由用户输入过文本,若尚未输入过,则不显示输入检查的失败。
''' </summary>
Private IsTextChanged As Boolean = False
Private _HintText As String = ""
Public Property HintText As String
Get
Return _HintText
End Get
Set(value As String)
_HintText = value
If labHint IsNot Nothing Then labHint.Text = If(Text = "", HintText, "")
End Set
End Property
Private Sub MyTextBox_TextChanged(sender As MyTextBox, e As TextChangedEventArgs) Handles Me.TextChanged
Try
'改变提示文本
If labHint IsNot Nothing Then labHint.Text = If(Text = "", HintText, "")
'改变输入记录
IsTextChanged = IsLoaded
'进行输入验证
Validate()
If Not ValidateResult = "" Then Exit Sub
'改变文本
RaiseEvent ValidatedTextChanged(sender, e)
Catch ex As Exception
Log(ex, "进行输入验证时出错", LogLevel.Assert)
End Try
End Sub
'颜色
Private Sub RefreshColor() Handles Me.IsEnabledChanged, Me.MouseEnter, Me.MouseLeave, Me.GotFocus, Me.LostFocus
Try
'手动关闭动画
If Not HasAnimation Then Exit Sub
'不对 ComboBox 从属进行动画
If TemplatedParent IsNot Nothing AndAlso TypeOf TemplatedParent Is MyComboBox Then Exit Sub
'判断当前颜色
Dim ForeColorName As String, BackColorName As String
Dim AnimationTime As Integer
If IsEnabled Then
If ValidateResult = "" OrElse Not IsTextChanged Then
If IsFocused Then
ForeColorName = "ColorBrush4"
BackColorName = "ColorBrush9"
AnimationTime = 60
ElseIf IsMouseOver Then
ForeColorName = "ColorBrush3"
BackColorName = "ColorBrushHalfWhite"
AnimationTime = 100
Else
ForeColorName = "ColorBrush1"
BackColorName = "ColorBrushHalfWhite"
AnimationTime = 200
End If
Else
ForeColorName = "ColorBrushRedLight"
BackColorName = "ColorBrushRedBack"
AnimationTime = 200
'If IsFocused OrElse IsMouseOver Then
' ForeColorName = "ColorBrushRedLight"
' BackColorName = "ColorBrushRedBack"
' AnimationTime = 100
'Else
' ForeColorName = "ColorBrushRedDark"
' BackColorName = "ColorBrushHalfWhite"
' AnimationTime = 200
'End If
End If
Else
ForeColorName = "ColorBrushGray4"
BackColorName = "ColorBrushHalfWhite"
AnimationTime = 200
End If
'触发颜色动画
If IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画
'有动画
AniStart({
AaColor(Me, BorderBrushProperty, ForeColorName, AnimationTime),
AaColor(Me, BackgroundProperty, BackColorName, AnimationTime)
}, "MyTextBox Color " & Uuid)
Else
'无动画
AniStop("MyTextBox Color " & Uuid)
SetResourceReference(BorderBrushProperty, ForeColorName)
SetResourceReference(BackgroundProperty, BackColorName)
End If
Catch ex As Exception
Log(ex, "文本框颜色改变出错")
End Try
End Sub
Private Sub RefreshTextColor() Handles Me.IsEnabledChanged
Dim NewColor As MyColor = If(IsEnabled, ColorGray1, ColorGray4)
If CType(Foreground, SolidColorBrush).Color.R = NewColor.R Then Exit Sub
If IsLoaded AndAlso AniControlEnabled = 0 AndAlso Not Text = "" Then
'有动画
AniStart({AaColor(Me, ForegroundProperty, If(IsEnabled, "ColorBrushGray1", "ColorBrushGray4"), 200)}, "MyTextBox TextColor " & Uuid)
Else
'无动画
AniStop("MyTextBox TextColor " & Uuid)
Foreground = NewColor
End If
End Sub
End Class