0
我有一個附加的行爲問題。當我將行爲附加到我的文本框時,我失去了所有基本功能,如最大長度?這是我如何將它附加到我的xaml中。當我脫下附加的行爲時,最大長度工作,當我把它放回它不起作用?任何幫助將不勝感激!Wpf AttachedBehavior在使用時失去基本文本框功能
這是類我使用
進口System.Windows 進口System.Windows.Controls 進口System.Globalization
命名空間AttachedBehaviours
Public Class TextBoxMaskBehavior
Inherits DependencyObject
區「 MinimumValue Property「
Public Shared Function GetMinimumValue(ByVal obj As DependencyObject) As Double
Return CDbl(obj.GetValue(MinimumValueProperty))
End Function
Public Shared Sub SetMinimumValue(ByVal obj As DependencyObject, ByVal value As Double)
obj.SetValue(MinimumValueProperty, value)
End Sub
Public Shared ReadOnly MinimumValueProperty As DependencyProperty = DependencyProperty.RegisterAttached("MinimumValue", GetType(Double), GetType(TextBoxMaskBehavior), New FrameworkPropertyMetadata(Double.NaN, AddressOf MinimumValueChangedCallback))
Private Shared Sub MinimumValueChangedCallback(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
Dim _this As TextBox = TryCast(d, TextBox)
ValidateTextBox(_this)
End Sub
端部區域
地區 「MaximumValue屬性」
Public Shared Function GetMaximumValue(ByVal obj As DependencyObject) As Double
Return CDbl(obj.GetValue(MaximumValueProperty))
End Function
Public Shared Sub SetMaximumValue(ByVal obj As DependencyObject, ByVal value As Double)
obj.SetValue(MaximumValueProperty, value)
End Sub
Public Shared ReadOnly MaximumValueProperty As DependencyProperty = DependencyProperty.RegisterAttached("MaximumValue", GetType(Double), GetType(TextBoxMaskBehavior), New FrameworkPropertyMetadata(Double.NaN, AddressOf MaximumValueChangedCallback))
Private Shared Sub MaximumValueChangedCallback(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
Dim _this As TextBox = TryCast(d, TextBox)
ValidateTextBox(_this)
End Sub
端部區域
地區 「Mask屬性」
Public Shared Function GetMask(ByVal obj As DependencyObject) As MaskType
Return CType(obj.GetValue(MaskProperty), MaskType)
End Function
Public Shared Sub SetMask(ByVal obj As DependencyObject, ByVal value As MaskType)
obj.SetValue(MaskProperty, value)
End Sub
Public Shared ReadOnly MaskProperty As DependencyProperty = DependencyProperty.RegisterAttached("Mask", GetType(MaskType), GetType(TextBoxMaskBehavior), New FrameworkPropertyMetadata(AddressOf MaskChangedCallback))
Private Shared Sub MaskChangedCallback(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
If TypeOf e.OldValue Is TextBox Then
RemoveHandler TryCast(e.OldValue, TextBox).PreviewTextInput, AddressOf TextBox_PreviewTextInput
DataObject.RemovePastingHandler(TryCast(e.OldValue, TextBox), DirectCast(AddressOf TextBoxPastingEventHandler, DataObjectPastingEventHandler))
End If
Dim _this As TextBox = TryCast(d, TextBox)
If _this Is Nothing Then
Return
End If
If CType(e.NewValue, MaskType) <> MaskType.Any Then
AddHandler _this.PreviewTextInput, AddressOf TextBox_PreviewTextInput
DataObject.AddPastingHandler(_this, DirectCast(AddressOf TextBoxPastingEventHandler, DataObjectPastingEventHandler))
End If
ValidateTextBox(_this)
End Sub
端部區域
區 「私人靜態方法」
Private Shared Sub ValidateTextBox(ByVal _this As TextBox)
If GetMask(_this) <> MaskType.Any Then
_this.Text = ValidateValue(GetMask(_this), _this.Text, GetMinimumValue(_this), GetMaximumValue(_this))
End If
End Sub
Private Shared Sub TextBoxPastingEventHandler(ByVal sender As Object, ByVal e As DataObjectPastingEventArgs)
Dim _this As TextBox = TryCast(sender, TextBox)
Dim clipboard As String = TryCast(e.DataObject.GetData(GetType(String)), String)
clipboard = ValidateValue(GetMask(_this), clipboard, GetMinimumValue(_this), GetMaximumValue(_this))
If Not String.IsNullOrEmpty(clipboard) Then
_this.Text = clipboard
End If
e.CancelCommand()
e.Handled = True
End Sub
Private Shared Sub TextBox_PreviewTextInput(ByVal sender As Object, ByVal e As System.Windows.Input.TextCompositionEventArgs)
Dim _this As TextBox = TryCast(sender, TextBox)
Dim isValid As Boolean = IsSymbolValid(GetMask(_this), e.Text)
e.Handled = Not isValid
If isValid Then
Dim caret As Integer = _this.CaretIndex
Dim text As String = _this.Text
Dim textInserted As Boolean = False
Dim selectionLength As Integer = 0
If _this.SelectionLength > 0 Then
text = text.Substring(0, _this.SelectionStart) & text.Substring(_this.SelectionStart + _this.SelectionLength)
caret = _this.SelectionStart
End If
If e.Text = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator Then
While True
Dim ind As Integer = text.IndexOf(NumberFormatInfo.CurrentInfo.NumberDecimalSeparator)
If ind = -1 Then
Exit While
End If
text = text.Substring(0, ind) & text.Substring(ind + 1)
If caret > ind Then
caret -= 1
End If
End While
If caret = 0 Then
text = "0" & text
caret += 1
Else
If caret = 1 AndAlso String.Empty & text(0) = NumberFormatInfo.CurrentInfo.NegativeSign Then
text = NumberFormatInfo.CurrentInfo.NegativeSign & "0" & text.Substring(1)
caret += 1
End If
End If
If caret = text.Length Then
selectionLength = 1
textInserted = True
text = text & NumberFormatInfo.CurrentInfo.NumberDecimalSeparator & "0"
caret += 1
End If
ElseIf e.Text = NumberFormatInfo.CurrentInfo.NegativeSign Then
textInserted = True
If _this.Text.Contains(NumberFormatInfo.CurrentInfo.NegativeSign) Then
text = text.Replace(NumberFormatInfo.CurrentInfo.NegativeSign, String.Empty)
If caret <> 0 Then
caret -= 1
End If
Else
text = NumberFormatInfo.CurrentInfo.NegativeSign + _this.Text
caret += 1
End If
End If
If Not textInserted Then
text = text.Substring(0, caret) & Convert.ToString(e.Text) & (If((caret < _this.Text.Length), text.Substring(caret), String.Empty))
caret += 1
End If
Try
Dim val As Double = Convert.ToDouble(text)
Dim newVal As Double = ValidateLimits(GetMinimumValue(_this), GetMaximumValue(_this), val)
If val <> newVal Then
text = newVal.ToString()
ElseIf val = 0 Then
If Not text.Contains(NumberFormatInfo.CurrentInfo.NumberDecimalSeparator) Then
text = "0"
End If
End If
Catch
text = "0"
End Try
While text.Length > 1 AndAlso text(0) = "0"c AndAlso String.Empty & text(1) <> NumberFormatInfo.CurrentInfo.NumberDecimalSeparator
text = text.Substring(1)
If caret > 0 Then
caret -= 1
End If
End While
While text.Length > 2 AndAlso String.Empty & text(0) = NumberFormatInfo.CurrentInfo.NegativeSign AndAlso text(1) = "0"c AndAlso String.Empty & text(2) <> NumberFormatInfo.CurrentInfo.NumberDecimalSeparator
text = NumberFormatInfo.CurrentInfo.NegativeSign & text.Substring(2)
If caret > 1 Then
caret -= 1
End If
End While
If caret > text.Length Then
caret = text.Length
End If
_this.Text = text
_this.CaretIndex = caret
_this.SelectionStart = caret
_this.SelectionLength = selectionLength
e.Handled = True
End If
End Sub
Private Shared Function ValidateValue(ByVal mask As MaskType, ByVal value As String, ByVal min As Double, ByVal max As Double) As String
If String.IsNullOrEmpty(value) Then
Return String.Empty
End If
value = value.Trim()
Select Case mask
Case MaskType.[Integer]
Try
Convert.ToInt64(value)
Return value
Catch
End Try
Return String.Empty
Case MaskType.[Decimal]
Try
Convert.ToDouble(value)
Return value
Catch
End Try
Return String.Empty
End Select
Return value
End Function
Private Shared Function ValidateLimits(ByVal min As Double, ByVal max As Double, ByVal value As Double) As Double
If Not min.Equals(Double.NaN) Then
If value < min Then
Return min
End If
End If
If Not max.Equals(Double.NaN) Then
If value > max Then
Return max
End If
End If
Return value
End Function
Private Shared Function IsSymbolValid(ByVal mask As MaskType, ByVal str As String) As Boolean
Select Case mask
Case MaskType.Any
Return True
Case MaskType.[Integer]
If str = NumberFormatInfo.CurrentInfo.NegativeSign Then
Return True
End If
Exit Select
Case MaskType.[Decimal]
If str = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator OrElse str = NumberFormatInfo.CurrentInfo.NegativeSign Then
Return True
End If
Exit Select
End Select
If mask.Equals(MaskType.[Integer]) OrElse mask.Equals(MaskType.[Decimal]) Then
For Each ch As Char In str
If Not [Char].IsDigit(ch) Then
Return False
End If
Next
Return True
End If
Return False
End Function
端部區域
End Class
Public Enum MaskType
Any
[Integer]
[Decimal]
End Enum
末命名空間