Pergunta

Estou fazendo uma aplicação WinForms Financeiro e estou tendo alguns problemas com os controles.

As minhas necessidades do cliente para inserir valores decimais em todo o lugar (preços, descontos etc) e eu gostaria de evitar algumas da validação repetindo.

Então eu imediatamente tentou o MaskedTextBox que se encaixam minhas necessidades (com uma máscara como "€ 00.000,00"), se não fosse para o foco e o comprimento da máscara.

Eu não posso prever o quão grande os números são o meu cliente vai entrar no aplicativo.

Eu também não pode esperar que ele comece tudo com 00 para chegar à vírgula. Tudo deve ser amigável para o teclado.

Estou faltando alguma coisa ou há simplesmente nenhuma maneira (além de escrever um controle personalizado) para alcançar este objectivo com os controles do Windows Forms padrão?

Foi útil?

Solução

Este dois métodos substituídos fez isso por mim (disclaimer:., Este código não está em produção ainda Você pode precisar modificar)

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

Outras dicas

Você vai precisar de um controle personalizado. armadilha apenas o evento Validando no controle e verificação se a entrada de string pode ser analisado como um decimal.

Eu não acho que você precisa de um controle personalizado, basta escrever um método decimal validando para o evento validar e usar isso para todos os lugares que você precisa para validar. Não se esqueça de incluir o NumberFormatInfo , ele vai lidar com vírgulas e sinais numebr.

Você só precisa deixar números e símbolos decimais through, e evitar um símbolo duplo decimal. Como um extra, este adiciona automaticamente a 0 antes de um número decimal começando.

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

Outra abordagem é bloquear o que você não quer, e formato quando o seu feito com ele.

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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top