我希望接受数字和小数点,但没有符号。

我已经看过使用Windows窗体中的NumericUpDown控件的示例,以及来自微软的这个NumericUpDown自定义控件的示例。但到目前为止,似乎NumericUpDown (WPF是否支持)不会提供我想要的功能。我的应用程序是这样设计的,任何头脑正常的人都不会想弄乱箭头。在我的应用程序中,它们没有任何实际意义。

所以我正在寻找一个简单的方法,使一个标准的WPF文本框只接受我想要的字符。这可能吗?实用吗?


当前回答

受雷的启发,我有一个简单的解决方案。这应该足以识别任何形式的数字。

如果您只想要正数、整数值或精确到小数点后最大位数的值,则可以轻松修改此解决方案。


正如Ray的回答所建议的,你需要首先添加一个PreviewTextInput事件:

<TextBox PreviewTextInput="TextBox_OnPreviewTextInput"/>

然后把下面的代码放在后面:

private void TextBox_OnPreviewTextInput(object sender, TextCompositionEventArgs e)
{
    var textBox = sender as TextBox;
    // Use SelectionStart property to find the caret position.
    // Insert the previewed text into the existing text in the textbox.
    var fullText = textBox.Text.Insert(textBox.SelectionStart, e.Text);

    double val;
    // If parsing is successful, set Handled to false
    e.Handled = !double.TryParse(fullText, out val);
}

对于无效的空格,我们可以添加NumberStyles:

using System.Globalization;

private void TextBox_OnPreviewTextInput(object sender, TextCompositionEventArgs e)
{
    var textBox = sender as TextBox;
    // Use SelectionStart property to find the caret position.
    // Insert the previewed text into the existing text in the textbox.
    var fullText = textBox.Text.Insert(textBox.SelectionStart, e.Text);

    double val;
    // If parsing is successful, set Handled to false
    e.Handled = !double.TryParse(fullText, 
                                 NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, 
                                 CultureInfo.InvariantCulture,
                                 out val);
}

其他回答

在Windows窗体中,这很容易;你可以添加一个事件按键和一切工作轻松。然而,在WPF中该事件不存在。但是有一个更简单的方法。

WPF文本框有TextChanged事件,这是一般的一切。它包括粘贴,输入和任何你能想到的东西。

所以你可以这样做:

XAML:

<TextBox name="txtBox1" ... TextChanged="TextBox_TextChanged"/>

背后的代码:

private void TextBox_TextChanged(object sender, TextChangedEventArgs e) {
    string s = Regex.Replace(((TextBox)sender).Text, @"[^\d.]", "");
    ((TextBox)sender).Text = s;
}

这也是可以接受的。,如果你不想要它,只需将它从正则表达式语句中删除为@[^\d]。

注意:此事件可以用于许多TextBox元素,因为它使用发送方对象的文本。您只需编写一次事件,并且可以将其用于多个TextBox元素。

添加一个验证规则,以便在文本更改时检查数据是否是数字,如果是,则允许继续处理,如果不是,则提示用户该字段中只接受数字数据。

请参阅Windows演示基础中的验证

也可以简单地实现一个验证规则,并将其应用到TextBox:

  <TextBox>
    <TextBox.Text>
      <Binding Path="OnyDigitInput" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
        <Binding.ValidationRules>
          <conv:OnlyDigitsValidationRule />
        </Binding.ValidationRules>
      </Binding>
    </TextBox.Text>

实现如下规则(使用与其他答案中建议的相同的Regex):

public class OnlyDigitsValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        var validationResult = new ValidationResult(true, null);

        if(value != null)
        {
            if (!string.IsNullOrEmpty(value.ToString()))
            {
                var regex = new Regex("[^0-9.-]+"); //regex that matches disallowed text
                var parsingOk = !regex.IsMatch(value.ToString());
                if (!parsingOk)
                {
                    validationResult = new ValidationResult(false, "Illegal Characters, Please Enter Numeric Value");
                }
            }
        }

        return validationResult;
    }
}

现在我知道这个问题有一个公认的答案,但就我个人而言,我觉得它有点令人困惑,我相信它应该比这更容易。所以我会试着演示我是如何做到最好的:

在Windows窗体中,有一个叫KeyPress的事件非常适合这类任务。但这在WPF中不存在,因此,我们将使用PreviewTextInput事件。此外,为了验证,我相信可以使用foreach来遍历文本框。Text并检查它是否匹配;)条件,但老实说,这就是正则表达式的用途。

在我们深入讨论神圣的法典之前还有一件事。对于要触发的事件,可以做两件事:

使用XAML告诉程序调用哪个函数:<PreviewTextInput="textBox_PreviewTextInput/> . 做它在加载事件的形式(文本框是在): 文本框。PreviewTextInput += onlyNumeric;

我认为第二种方法更好,因为在这种情况下,你会被要求应用相同的条件(正则表达式)到多个文本框,你不想重复自己!

最后,你可以这样做:

private void onlyNumeric(object sender, TextCompositionEventArgs e)
{
    string onlyNumeric = @"^([0-9]+(.[0-9]+)?)$";
    Regex regex = new Regex(onlyNumeric);
    e.Handled = !regex.IsMatch(e.Text);
}
PreviewTextInput += (s, e) =>
{
    e.Handled = !e.Text.All(char.IsDigit);
};