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

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

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


当前回答

下面是WPF中用于数字输入的库

它具有NumberStyles和regexpattern等用于验证的属性。

WPF文本框的子类

其他回答

这是我的版本。它基于一个基本的ValidatingTextBox类,如果它不是“有效”的,它只是撤销已经做过的事情。它支持粘贴,剪切,删除,退格,+,-等。

对于32位整型,有一个Int32TextBox类用于与整型进行比较。我还添加了浮点验证类。

public class ValidatingTextBox : TextBox
{
    private bool _inEvents;
    private string _textBefore;
    private int _selectionStart;
    private int _selectionLength;

    public event EventHandler<ValidateTextEventArgs> ValidateText;

    protected override void OnPreviewKeyDown(KeyEventArgs e)
    {
        if (_inEvents)
            return;

        _selectionStart = SelectionStart;
        _selectionLength = SelectionLength;
        _textBefore = Text;
    }

    protected override void OnTextChanged(TextChangedEventArgs e)
    {
        if (_inEvents)
            return;

        _inEvents = true;
        var ev = new ValidateTextEventArgs(Text);
        OnValidateText(this, ev);
        if (ev.Cancel)
        {
            Text = _textBefore;
            SelectionStart = _selectionStart;
            SelectionLength = _selectionLength;
        }
        _inEvents = false;
    }

    protected virtual void OnValidateText(object sender, ValidateTextEventArgs e) => ValidateText?.Invoke(this, e);
}

public class ValidateTextEventArgs : CancelEventArgs
{
    public ValidateTextEventArgs(string text) => Text = text;

    public string Text { get; }
}

public class Int32TextBox : ValidatingTextBox
{
    protected override void OnValidateText(object sender, ValidateTextEventArgs e) => e.Cancel = !int.TryParse(e.Text, out var value);
}

public class Int64TextBox : ValidatingTextBox
{
    protected override void OnValidateText(object sender, ValidateTextEventArgs e) => e.Cancel = !long.TryParse(e.Text, out var value);
}

public class DoubleTextBox : ValidatingTextBox
{
    protected override void OnValidateText(object sender, ValidateTextEventArgs e) => e.Cancel = !double.TryParse(e.Text, out var value);
}

public class SingleTextBox : ValidatingTextBox
{
    protected override void OnValidateText(object sender, ValidateTextEventArgs e) => e.Cancel = !float.TryParse(e.Text, out var value);
}

public class DecimalTextBox : ValidatingTextBox
{
    protected override void OnValidateText(object sender, ValidateTextEventArgs e) => e.Cancel = !decimal.TryParse(e.Text, out var value);
}

注意1:在使用WPF绑定时,必须确保使用符合绑定属性类型的类,否则可能会导致奇怪的结果。

注意2:在WPF绑定中使用浮点类时,请确保绑定使用当前区域性来匹配我使用的TryParse方法。

我们可以对文本框更改事件进行验证。下面的实现可以防止除数字和一个小数点以外的按键输入。

private void textBoxNumeric_TextChanged(object sender, TextChangedEventArgs e) 
{         
      TextBox textBox = sender as TextBox;         
      Int32 selectionStart = textBox.SelectionStart;         
      Int32 selectionLength = textBox.SelectionLength;         
      String newText = String.Empty;         
      int count = 0;         
      foreach (Char c in textBox.Text.ToCharArray())         
      {             
         if (Char.IsDigit(c) || Char.IsControl(c) || (c == '.' && count == 0))             
         {                 
            newText += c;                 
            if (c == '.')                     
              count += 1;             
         }         
     }         
     textBox.Text = newText;         
     textBox.SelectionStart = selectionStart <= textBox.Text.Length ? selectionStart :        textBox.Text.Length;     
} 

当检查数字值时,您可以使用VisualBasic。IsNumeric函数。

在WPF应用程序中,你可以通过处理TextChanged事件来处理这个:

void arsDigitTextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
    Regex regex = new Regex("[^0-9]+");
    bool handle = regex.IsMatch(this.Text);
    if (handle)
    {
        StringBuilder dd = new StringBuilder();
        int i = -1;
        int cursor = -1;
        foreach (char item in this.Text)
        {
            i++;
            if (char.IsDigit(item))
                dd.Append(item);
            else if(cursor == -1)
                cursor = i;
        }
        this.Text = dd.ToString();

        if (i == -1)
            this.SelectionStart = this.Text.Length;
        else
            this.SelectionStart = cursor;
    }
}

我允许数字键盘号码和退格:

    private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        int key = (int)e.Key;

        e.Handled = !(key >= 34 && key <= 43 || 
                      key >= 74 && key <= 83 || 
                      key == 2);
    }