Create WPF TextBox that accepts only numbers [dupl

2019-01-11 10:21发布

This question already has an answer here:

I would like to create a TextBox that only accepts numeric values, in a specific range. What is the best way to implement such TextBox?

I thought about deriving TextBox and to override the validation and coercion of the TextProperty. However, I am not sure how to do this, and I understand that deriving WPF control is generally not recommended.


Edit:
What I needed was a very basic textbox that filters out all key presses which are not digits. The easiest way to achieve it is to handle the TextBox.PreviewTextInput event:

private void textBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
    int result;
    if (!validateStringAsNumber(e.Text,out result,false))
    {
        e.Handled = true;
    }
}

(validateStringAsNumber is my function that primarily use Int.TryParse)

Some of the suggested solutions are probably better, but for the simple functionality I needed this solution is the easiest and quickest to implement while sufficient for my needs.

标签: c# wpf textbox
5条回答
我只想做你的唯一
2楼-- · 2019-01-11 10:57

The overall best why is to use the override method OnKeyPressed for the textbox like. Here is the code for the override using the static Char Method IsDigit.

if (!Char.IsDigit(e.KeyChar) && !Char.IsControl(e.KeyChar)) e.Handled = true;

That is all you really need to do.

查看更多
【Aperson】
3楼-- · 2019-01-11 10:58

This would be my preferred approach:

private void yearTxt_PreviewKeyDown(object sender, KeyEventArgs e)
{
  switch (e.Key)
  {
    case Key.D0:
    case Key.D1:
    case Key.D2:
    case Key.D3:
    case Key.D4:
    case Key.D5:
    case Key.D6:
    case Key.D7:
    case Key.D8:
    case Key.D9:
    case Key.NumLock:
    case Key.NumPad0:
    case Key.NumPad1:
    case Key.NumPad2:
    case Key.NumPad3:
    case Key.NumPad4:
    case Key.NumPad5:
    case Key.NumPad6:
    case Key.NumPad7:
    case Key.NumPad8:
    case Key.NumPad9:
    case Key.Back:
      break;
    default:
      e.Handled = true;
      break;
  }
}
查看更多
不美不萌又怎样
4楼-- · 2019-01-11 11:02

Most implementations I have seen so far are using the PreviewTextInput event to implement the correct mask behavior. This one inherits from TextBox and this one uses attached properties. Both use .Net's MaskedTextProvider to provide the correct mask behaviour, but if you just want a simple 'numbers only' textbox you don't need this class.

查看更多
该账号已被封号
5楼-- · 2019-01-11 11:19
private void txt_TextChanged(object sender, TextChangedEventArgs e)
{
    TextBox textBox = sender as TextBox;
    int iValue = -1;

    if (Int32.TryParse(textBox.Text, out iValue) == false)
    {
         TextChange textChange = e.Changes.ElementAt<TextChange>(0);
         int iAddedLength = textChange.AddedLength;
         int iOffset = textChange.Offset;

         textBox.Text = textBox.Text.Remove(iOffset, iAddedLength);
    }
}
查看更多
SAY GOODBYE
6楼-- · 2019-01-11 11:19

In my humble opinion, the best way to fulfill this requirement is using only OnTextChanged event because it can handle the digit from keystroke and also be able to handle Copy+Paste from clipboard too. I hope that my VB code shown below can throw some light on this.

Private Sub NumericBox_TextChanged(sender As Object, e As TextChangedEventArgs) Handles Me.TextChanged
  Dim Buffer As New StringBuilder
  Dim Index As Integer = Me.SelectionStart
  For Each C In Me.Text
    If Char.IsDigit(C) Then
      Buffer.Append(C)
    ElseIf Me.SelectionStart > Buffer.Length Then
      Index -= 1
    End If
  Next
  Me.Text = Buffer.ToString
  Me.SelectionStart = Index
End Sub
查看更多
登录 后发表回答