输入小数点时TextBox无法正确更新

时间:2015-06-11 19:42:36

标签: wpf vb.net binding inotifypropertychanged

我有一些奇怪的行为,我无法弄明白。我有一个绑定到字符串属性的文本框(表示数字值)。 getter应格式化我的字符串以包含4位十进制数字。这很有用,但在输入带小数值的数字时会给用户带来非直观的惊喜。

  

示例:如果用户想要输入5.1,则输入5 - > 。 - > 1导致TextBox格式化为   “5.0000” - > “中5..0000” - > “中5.1.0000”

所以我添加了额外的逻辑来用一个小数点替换任何连续的小数点。这是我的奇怪问题开始出现的地方。用户可以输入“5 ..... 1”,并且UI似乎不会随着连续小数点的删除而更新。但是,在这些小数点之间键入任何字符会触发它以正确删除连续的小数点:

  

示例:在最后一个小数点(“5 .... 2.1”)之前键入2   在“5.2.1”中,这是我所期待的。

如果我单步执行代码,返回的值似乎总是正确格式化,没有连续的小数点。然而,UI仍显示“5 ..... 1”。如果我直接编辑小数点(输入更多或删除现有小数点),UI似乎不会更新,但是在它们之间输入或删除字符会触发预期的更新。

这是ViewModel中的属性:

Private _valueString As String
Public Property ValueString As String
    Get
        Dim formattedString As String = Double.NaN.ToString
        Dim tempDouble As Double
        Dim rgx As New Regex("\.+")

        If Double.TryParse(_ValueString, tempDouble) Then
            formattedString = tempDouble.ToString("F4")
            formattedString = rgx.Replace(formattedString, ".")
        Else
            formattedString = rgx.Replace(_valueString, ".")
        End If

        Return formattedString
    End Get
    Set(value As String)
        Dim rgx As New Regex("\.+")
        _ValueString = rgx.Replace(value, ".")

        NotifyPropertyChanged("ValueString")
    End Set
End Property

XAML:

<TextBox Text="{Binding ValueString, UpdateSourceTrigger=PropertyChanged}" />

有关导致其未更新的原因的任何想法?为什么用户能够连续输入多个小数点?

2 个答案:

答案 0 :(得分:0)

尝试使用Text="{Binding ValueString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

除此之外,我认为您应该将Textbox绑定到double属性并使用验证器,以便根本不设置无法解析为double的输入。

答案 1 :(得分:-1)

我会将您的updatesourcetrigger设置为LostFocus(默认)并在文本框的textchanged事件中设置以下内容。这样您就可以在小数位后继续输入数字。如果最后没有小数位,它将更新,就像你将触发器设置为PropertyChanged一样。

更新源函数手动执行触发器将触发的内容。

为了这个例子,我的文本框被称为txbAmount。

VB

Private Sub txbAmount_TextChanged(sender As Object, e As TextChangedEventArgs)
        If Me.txbAmount.Text IsNot Nothing Then
            If Me.txbAmount.Text.Count() > 0 Then
                If Me.txbAmount.Text.Last() <> "."C Then
                    Me.txbAmount.GetBindingExpression(TextBox.TextProperty).UpdateSource()
                End If
            End If
        End If
    End Sub

C#

private void txbAmount_TextChanged(object sender, TextChangedEventArgs e)
    {
        if (this.txbAmount.Text != null)
        {
            if (this.txbAmount.Text.Count() > 0)
            {
                if (this.txbAmount.Text.Last() != '.')
                {
                    this.txbAmount.GetBindingExpression(TextBox.TextProperty).UpdateSource();
                }
            }
        }
    }