Pergunta

Eu tenho um problema de comportamento em anexo. Quando anexo o comportamento à minha caixa de texto, perco toda a minha funcionalidade base, como o comprimento máximo? Aqui está como estou anexando -o no meu xaml. Quando tiro o comportamento em anexo, o comprimento máximo funciona quando o coloco de volta, não funciona? Qualquer ajuda seria muito apreciada!

Esta é a classe que estou usando

Imports System.Windows Imports System.Windows.Controls Imports System.GLOBALIZAÇÃO

Namespace anexadoBehaviours

Public Class TextBoxMaskBehavior
    Inherits DependencyObject

Região "Propriedade Minimumumvalue"

    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

Região final

Região "Propriedade 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

Região final

Região "Propriedade de máscara"

    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

Região final

Região "Métodos estáticos privados"

    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

Região final

End Class

Public Enum MaskType
    Any
    [Integer]
    [Decimal]
End Enum

Namespace final

Foi útil?

Solução

Descobriu a solução. Estou testando o comprimento do texto e certifico -se de que seja <o comprimento máximo.

Se não for, textInserted, se _This.Text.Length <_This.MaxLength então text = text.substring (0, Caret) & convert.toString (eText) & (if ((caret <_this.text.length), texto. Substring (Caret), String.Empty))

                    caret += 1
                End If

            End If

Usou isso na função inteira.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top