Coder1095
Coder1095

Reputation: 828

TextBox bound to DateTime via converter formats itself while typing

I have a TextBox bound to a DateTime using a converter that implements Convert and ConvertBack. UpdateSourceTrigger is set to PropertyChanged so that validation is done as the user types. Here is the problem:

  1. User types a character
  2. Converter parses this to a DateTime
  3. Property in ViewModel is updated and validated
  4. Converter then converts this DateTime back into a string and changes the string in the text box

This is undesirable as the text can change to a full date while the user has only typed part of a date. How can I stop the UI from doing this? Note that this has only become a problem since upgrading from .NET 3.5 to 4.0 because of this feature:

http://karlshifflett.wordpress.com/2009/05/27/wpf-4-0-data-binding-change-great-feature/

Thanks for any help!

Upvotes: 1

Views: 378

Answers (2)

Loc
Loc

Reputation: 1

Try this:

Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    'Limit the length of the number that can be entered to 12 (This is arbitrary)
    If Len(TextBox1.Text) > 12 Then
        KeyAscii = 0
        Exit Sub
    End If

    If KeyAscii < 32 Then
        Exit Sub    ' let it go, it is a control char like backspace
    End If

    If InStr("0123456789.", Chr$(KeyAscii)) > 0 Then
        If InStr(TextBox1.Text, ".") > 0 Then
            If Chr$(KeyAscii) = "." Then
                KeyAscii = 0    ' do not allow more than one decimal point
                Beep
                MsgBox "Only 2 decimal places to be allowed", vbCritical
                Exit Sub

            ElseIf Len(Mid$(TextBox1.Text, InStr(TextBox1.Text, ".") + 1)) >= 2 Then
                KeyAscii = 0    ' do not allow more than 2 digits past decimal point
                Beep
                MsgBox "Only 2 decimal places to be allowed", vbCritical
                Exit Sub

            End If
        End If
    Else
        Beep
        KeyAscii = 0
    End If

    If Len(Mid$(TextBox1.Text, InStr(TextBox1.Text, "$") + 1)) >= 1 Or KeyAscii < 32 Then
        If Len(Mid$(TextBox1.Text, InStr(TextBox1.Text, ".") + 1)) >= 2 Then

            If KeyAscii < 32 Then Beep: Exit Sub
            TextBox1.Text = Format(TextBox1.Text, "$#,###")
        Else
            If KeyAscii < 32 Then Beep: Exit Sub
            TextBox1.Text = TextBox1.Text
        End If
    ElseIf Len(Mid$(TextBox1.Text, InStr(TextBox1.Text, "$") + 1)) >= 0 Or KeyAscii < 32 Then
        If Len(Mid$(TextBox1.Text, InStr(TextBox1.Text, ".") + 1)) >= 2 Then

            If KeyAscii < 32 Then Beep: Exit Sub
            TextBox1.Text = Format(TextBox1.Text, "$#,###")
        Else
            If KeyAscii < 32 Then Beep: Exit Sub
            TextBox1.Text = ""
            TextBox1.Text = "$" & TextBox1.Text
        End If
    End If


End Sub
Private Sub TextBox1_Change()

    If Len(Mid$(TextBox1.Text, InStr(TextBox1.Text, ".") + 1)) >= 3 Then
        TextBox1.Value = Format(PaidCreditCardForfrm.TextBox1.Value, "$#,###")
    End If

End Sub

Upvotes: 0

Florian Gl
Florian Gl

Reputation: 6014

You could use Data Validation, which allows you to check if the typed value fulfills a certain condition (e.g. a regex) before the property gets the typed value -> Converter gets only called if the condition is fulfilled.
Another suggestion would be that you check in your Converter via a regex if the typed value is a DateTime and convert it only if it matches.

Upvotes: 1

Related Questions