Подтвердить что ты не робот

Создайте текстовый блок WPF, который принимает только числа

Я хотел бы создать TextBox, который принимает только числовые значения в определенном диапазоне. Каков наилучший способ реализовать такой TextBox?

Я думал о выводе TextBox и переопределении проверки и принуждения TextProperty. Однако я не уверен, как это сделать, и я понимаю, что получение WPF-контроля обычно не рекомендуется.


<Б > Изменить:
Мне нужен был очень простой текстовый блок, который отфильтровывает все нажатия клавиш, которые не являются цифрами. Самый простой способ добиться этого - обработать событие TextBox.PreviewTextInput:
private void textBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
    int result;
    if (!validateStringAsNumber(e.Text,out result,false))
    {
        e.Handled = true;
    }
}

(validateStringAsNumber - это моя функция, которая в основном использует Int.TryParse)

Некоторые из предлагаемых решений, вероятно, лучше, но для простой функциональности я нуждался в этом решении, которое было бы самым простым и быстрым в реализации, достаточным для моих нужд.

4b9b3361

Ответ 1

Большинство реализаций, которые я видел до сих пор, используют PreviewTextInput для реализации правильного поведения маски. Этот один наследует от TextBox и этот использует прилагаемые свойства. Оба используют .Net MaskedTextProvider, чтобы обеспечить правильное поведение маски, но если вам просто нужно простое текстовое поле с номерами, вам не нужно этот класс.

Ответ 2

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);
    }
}

Ответ 3

По моему скромному мнению, лучший способ выполнить это требование - использовать только событие OnTextChanged, потому что он может обрабатывать цифру от нажатия клавиши, а также иметь возможность обрабатывать Copy + Paste из буфера обмена. Я надеюсь, что мой код VB, показанный ниже, может пролить свет на это.

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

Ответ 4

В целом лучше всего использовать метод переопределения OnKeyPressed для текстового поля. Вот код для переопределения с использованием статического метода Char IsDigit.

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

Это все, что вам действительно нужно делать.

Ответ 5

Это был бы мой предпочтительный подход:

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;
  }
}