wpf TextBox绑定到double意外行为

yb3bgrhw  于 2022-12-05  发布在  其他
关注(0)|答案(1)|浏览(259)

我有一个绑定到doubleTextBox,必须在每次击键时验证它。我希望允许用户输入任何字符
由于某种我不理解的原因行为并不尽如人意。举例:

  • .3-接受,但更改为0.3;
  • abc123.-按原样接受;
  • 12.3-.不被接受,最终结果为123;
  • 123,将光标置于23之间,输入.-被接受为12.3

我无法想象这种行为是欲望的场景。我该如何解决它呢?

<TextBox Name="txtPrice"
         Text="{Binding Model.Price, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" />
qmb5sa22

qmb5sa221#

安迪(在注解中)是正确的-问题是来自UpdateSourceTrigger=PropertyChanged-这意味着每当你输入内容时,它会将其发送到backing属性,转换为double,然后作为该double发送回文本框。因此,如果你输入12.3,当你输入12.时,它会将其转换为double 12,然后将其放入框中。这对用户来说就像是去掉了小数点。你看到的其他结果也是类似的。

编辑:我之前误解了您的问题,以为您是要求阻止无效文本,而不是简单地验证它。以下是更新的答案

您可以将其设置为仅单向绑定,即从文本框绑定到绑定目标,以便转换后的值不会返回到文本框,方法是:

<TextBox Name="txtPrice"
    Text="{Binding Model.Price,
    ValidatesOnDataErrors=True,
    Mode=OneWayToSource,
    UpdateSourceTrigger=PropertyChanged}" />

这样做的缺点是修改Model.Price不再更新文本框中显示的值-它只传播TextBox -〉Model,而不是相反。如果这对你来说不是问题(例如它只是用于用户输入而不是编辑),那么就使用它。如果这是一个问题,那么你就必须编写自己的value converter来指定你想要的行为。

原始答案,关于阻止非数字输入:

如果你需要对每次击键进行验证,那么你需要使用类似PreviewTextInput的代码来验证什么文本可以进入文本框:
XAML语言

<TextBox Name="txtPrice"
PreviewTextInput="ValidateNumericInput"
Text="{Binding Model.Price,
ValidatesOnDataErrors=True,
UpdateSourceTrigger=Default}" />

C#语言

private void ValidateNumericInput(object sender, TextCompositionEventArgs e)
{
    var textBox = (TextBox)sender;
    var oldText = textBox.Text;

    var newText = oldText.Substring(0, textBox.SelectionStart) + e.Text + oldText.Substring(textBox.SelectionStart + textBox.SelectionLength);

    // If it's not valid, then ignore this text input
    if (!double.TryParse(newText, out var _) && newText != "." && newText != "-")
    {
        e.Handled = true;
    }
}

它的作用是判断您尝试输入的文本是否为有效的双精度值(或双精度值的开头),如果不是,则忽略它。
还将UpdateSourceTrigger更改为其默认值,这意味着双精度值不会反向传播到文本框。
请注意,当您将内容粘贴到文本框而不是键入内容时,PreviewTextInput不会被命中(完全不知道是MS的哪位天才决定了这一点),因此您仍然可以粘贴无效的输入。如果这对您来说是一个问题,请研究PasteHandlers以了解如何缓解此问题。
顺便说一句,WPF在这方面做得不好,你是对的--你不是第一个处理这个问题的人,也不会是最后一个。TextBox中的文本处理有很多奇怪的陷阱和边缘情况,这是一个麻烦。我不知道为什么他们不添加一个文本控件,让你设置有效性正则表达式或类似的东西。

相关问题