Pregunta

Estoy haciendo una aplicación de Financial Winforms y tengo algunos problemas con los controles.

Mi cliente necesita insertar valores decimales en todo el lugar (precios, descuentos, etc.) y me gustaría evitar la validación repetitiva.

Así que inmediatamente probé el MaskedTextBox que se ajustaría a mis necesidades (con una Máscara como " € 00000.00 "), si no fuera por el enfoque y la longitud de la máscara.

No puedo predecir qué tan grandes serán los números que mi cliente ingresará en la aplicación.

Tampoco puedo esperar que comience todo con 00 para llegar a la coma. Todo debería ser amigable con el teclado.

¿Me falta algo o simplemente no hay forma (más allá de escribir un control personalizado) para lograr esto con los controles estándar de Windows Forms?

¿Fue útil?

Solución

Estos dos métodos anulados lo hicieron por mí (exención de responsabilidad: este código aún no está en producción. Es posible que deba modificarlo)

    protected override void OnKeyPress(KeyPressEventArgs e)
    {
        if (!char.IsNumber(e.KeyChar) & (Keys)e.KeyChar != Keys.Back 
            & e.KeyChar != '.')
        {
            e.Handled = true;
        }

        base.OnKeyPress(e);
    }

    private string currentText;

    protected override void OnTextChanged(EventArgs e)
    {
        if (this.Text.Length > 0)
        {
            float result;
            bool isNumeric = float.TryParse(this.Text, out result);

            if (isNumeric)
            {
                currentText = this.Text;
            }
            else
            {
                this.Text = currentText;
                this.Select(this.Text.Length, 0);
            }
        }
        base.OnTextChanged(e);
    }

Otros consejos

Necesitará un control personalizado. Simplemente atrape el evento de Validación en el control y verifique si la entrada de la cadena se puede analizar como un decimal.

No creo que necesite un control personalizado, simplemente escriba un método de validación decimal para el evento de validación y utilícelo en todos los lugares que necesita validar. No olvide incluir el NumberFormatInfo , se ocupará de comas y signos numebr.

Solo tiene que dejar pasar los números y los símbolos decimales, y evitar un símbolo decimal doble. Como extra, esto agrega automáticamente un 0 antes de un número decimal inicial.

public class DecimalBox : TextBox
{
    protected override void OnKeyPress(KeyPressEventArgs e)
    {
        if (e.KeyChar == ',')
        {
            e.KeyChar = '.';
        }

        if (!char.IsNumber(e.KeyChar) && (Keys)e.KeyChar != Keys.Back && e.KeyChar != '.')
        {
            e.Handled = true;
        }

        if(e.KeyChar == '.' )
        {
            if (this.Text.Length == 0)
            {
                this.Text = "0.";
                this.SelectionStart = 2;
                e.Handled = true;
            }
            else if (this.Text.Contains("."))
            {
                e.Handled = true;
            }
        }

        base.OnKeyPress(e);
    }
}

Otro enfoque es bloquear lo que no deseas y formatear cuando hayas terminado con él.

class DecimalTextBox : TextBox
{
    // Handle multiple decimals
    protected override void OnKeyPress(KeyPressEventArgs e)
    {
        if (e.KeyChar == '.')
            if (this.Text.Contains('.'))
                e.Handled = true;

        base.OnKeyPress(e);
    }

    // Block non digits
    // I scrub characters here instead of handling in OnKeyPress so I can support keyboard events (ctrl + c/v/a)
    protected override void OnTextChanged(EventArgs e)
    {
        this.Text = System.Text.RegularExpressions.Regex.Replace(this.Text, "[^.0-9]", "");
        base.OnTextChanged(e);
    }

    // Apply our format when we're done
    protected override void OnLostFocus(EventArgs e)
    {
        if (!String.IsNullOrEmpty(this.Text))
            this.Text = string.Format("{0:N}", Convert.ToDouble(this.Text));

        base.OnLostFocus(e);
    }


}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top