【问题标题】:TextBox not updating properly when decimal point is input输入小数点时文本框未正确更新
【发布时间】:2015-06-11 19:42:35
【问题描述】:

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

示例:如果用户想输入 5.1,他们输入 5 -> 。 -> 1 导致 TextBox 格式化为 "5.0000"->"5..0000"->"5.1.0000"

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

示例:在最后一个小数点前输入 2 ("5....2.1") 结果 在“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}" />

关于导致它不更新的任何想法?为什么用户可以连续输入多个小数点?

【问题讨论】:

    标签: wpf vb.net binding inotifypropertychanged


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      我会将您的 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();
                      }
                  }
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-18
        • 2022-01-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多