Procurando um controle de edição numérico C# simples
Pergunta
Sou um programador MFC novo em C# e estou procurando um controle simples que permita a entrada de números e a validação de intervalo.
Solução
Observe o controle "NumericUpDown".Possui validação de intervalo, a entrada será sempre numérica e possui aqueles botões bacanas de incremento/decremento.
Outras dicas
Tive que implementar um Controle que aceitasse apenas números, inteiros ou reais.Eu construo o controle como uma especialização de (leia:derivado de) controle TextBox e usando controle de entrada e uma expressão regular para a validação.Adicionar validação de intervalo é extremamente fácil.
Este é o código para construir o regex._numericseparation é uma string com caracteres aceitos como valores de vírgula decimal (por exemplo, a '.' ou a ',':$10,50 10,50€
private string ComputeRegexPattern()
{
StringBuilder builder = new StringBuilder();
if (this._forcePositives)
{
builder.Append("([+]|[-])?");
}
builder.Append(@"[\d]*((");
if (!this._useIntegers)
{
for (int i = 0; i < this._numericSeparator.Length; i++)
{
builder.Append("[").Append(this._numericSeparator[i]).Append("]");
if ((this._numericSeparator.Length > 0) && (i != (this._numericSeparator.Length - 1)))
{
builder.Append("|");
}
}
}
builder.Append(@")[\d]*)?");
return builder.ToString();
}
A expressão regular corresponde a qualquer número (ou seja,qualquer string com caracteres numéricos) com apenas um caractere como separação numérica e um caractere opcional '+' ou '-' no início da string.Depois de criar a regex (ao instanciar o Controle), você verifica se o valor está correto substituindo o método OnValidating.CheckValidNumber() apenas aplica o Regex ao texto introduzido.Se a correspondência de regex falhar, ativa um provedor de erros com um erro especificado (definido com a propriedade pública ValidationError) e gera um evento ValidationError.Aqui você poderá fazer a verificação para saber se o número está na faixa exigida.
private bool CheckValidNumber()
{
if (Regex.Match(this.Text, this.RegexPattern).Value != this.Text)
{
this._errorProvider.SetError(this, this.ValidationError);
return false;
}
this._errorProvider.Clear();
return true;
}
protected override void OnValidating(CancelEventArgs e)
{
bool flag = this.CheckValidNumber();
if (!flag)
{
e.Cancel = true;
this.Text = "0";
}
base.OnValidating(e);
if (!flag)
{
this.ValidationFail(this, EventArgs.Empty);
}
}
Como eu disse, também evito que o usuário insira dados na caixa de texto que não sejam caracteres numéricos, substituindo o método OnKeyPress:
protected override void OnKeyPress(KeyPressEventArgs e)
{
if ((!char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar)) && (!this._numberSymbols.Contains(e.KeyChar.ToString()) && !this._numericSeparator.Contains(e.KeyChar.ToString())))
{
e.Handled = true;
}
if (this._numberSymbols.Contains(e.KeyChar.ToString()) && !this._forcePositives)
{
e.Handled = true;
}
if (this._numericSeparator.Contains(e.KeyChar.ToString()) && this._useIntegers)
{
e.Handled = true;
}
base.OnKeyPress(e);
}
O toque elegante:Verifico se o número é válido toda vez que o usuário libera uma chave, para que o usuário possa obter feedback enquanto digita.(Mas lembre-se que você deve ter cuidado com o evento ValidationFail;))
protected override void OnKeyUp(KeyEventArgs e)
{
this.CheckValidNumber();
base.OnKeyUp(e);
}
Você pode usar uma caixa de texto normal e um controle Validador para controlar a entrada.
Tente usar um controle de provedor de erros para validar a caixa de texto.Você pode usar int.TryParse() ou double.TryParse() para verificar se é numérico e então validar o intervalo.
Você pode usar uma combinação de RequiredFieldValidator e CompareValidator (definido como DataTypeCheck para o operador e Type definido como Integer)
Isso resultará em uma caixa de texto normal, se desejar; caso contrário, a recomendação acima é boa.