2010-09-29 81 views
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 

末命名空間

回答

0

想出解決方案。我正在測試文本的長度,並確保它的最大長度爲<。

如果不textInserted然後 如果_this.Text.Length < _this.MaxLength然後 文本= text.Substring(0,脫字符號)& Convert.ToString(e.Text)&(如果((脫字符號< _this.Text .Length),text.Substring(插入符號),String.Empty))

    caret += 1 
       End If 

      End If 

在整數函數中使用了這個。