que - validar solo numeros y letras c#
Crear WPF TextBox que acepta solo nĂºmeros (5)
Esta pregunta ya tiene una respuesta aquí:
Me gustaría crear un TextBox que solo acepte valores numéricos, en un rango específico. ¿Cuál es la mejor manera de implementar tal TextBox?
Pensé en derivar TextBox y anular la validación y coerción de TextProperty. Sin embargo, no estoy seguro de cómo hacer esto, y entiendo que generalmente no se recomienda derivar el control WPF.
Editar:Lo que necesitaba era un cuadro de texto muy básico que filtra todas las pulsaciones de teclas que no son dígitos. La forma más fácil de lograrlo es manejar el evento TextBox.PreviewTextInput:
private void textBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
int result;
if (!validateStringAsNumber(e.Text,out result,false))
{
e.Handled = true;
}
}
(validateStringAsNumber es mi función que usa principalmente Int.TryParse)
Algunas de las soluciones sugeridas son probablemente mejores, pero para la funcionalidad simple que necesitaba, esta es la más fácil y rápida de implementar, pero suficiente para mis necesidades.
La mayoría de las implementaciones que he visto hasta ahora están usando el evento PreviewTextInput para implementar el comportamiento correcto de la máscara. Este hereda de TextBox y este usa propiedades adjuntas. Ambos usan MaskedTextProvider de .Net para proporcionar el comportamiento correcto de la máscara, pero si solo quieres un simple cuadro de texto de "solo números" no necesitas esta clase.
El mejor motivo es usar el método de anulación OnKeyPressed
para el cuadro de texto. Aquí está el código para la anulación usando el IsDigit
Method IsDigit
estático.
if (!Char.IsDigit(e.KeyChar) && !Char.IsControl(e.KeyChar)) e.Handled = true;
Eso es todo lo que realmente necesitas hacer.
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);
}
}
Este sería mi enfoque preferido:
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;
}
}
En mi humilde opinión, la mejor manera de cumplir este requisito es usar únicamente el evento OnTextChanged
porque puede manejar el dígito de la pulsación de tecla y también ser capaz de manejar Copiar y Pegar desde el portapapeles. Espero que mi código VB que se muestra a continuación pueda arrojar algo de luz sobre esto.
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