Десятичное текстовое поле в Windows Forms - PullRequest
4 голосов
/ 28 октября 2008

Я работаю с приложением Financial Winforms и у меня возникли проблемы с элементами управления.

Моему клиенту нужно вставлять десятичные значения везде (цены, скидки и т. Д.), И я бы хотел избежать повторной проверки.

Поэтому я сразу же попробовал MaskedTextBox, который бы соответствовал моим потребностям (с маской типа «€ 00000.00»), если бы не фокус и длина маски.

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

Я также не могу ожидать, что он начнет все с 00, чтобы добраться до запятой. Все должно быть удобным для клавиатуры.

Я что-то упустил или просто нет способа (кроме написания пользовательского элемента управления) достичь этого с помощью стандартных элементов управления Windows Forms?

Ответы [ 6 ]

5 голосов
/ 28 октября 2008

Эти два переопределенных метода сделали это для меня (отказ от ответственности: этот код еще не работает. Возможно, вам придется изменить)

    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);
    }
5 голосов
/ 28 октября 2008

Вам понадобится пользовательский элемент управления. Просто перехватите событие Validating в элементе управления и проверьте, может ли входная строка анализироваться как десятичное число.

3 голосов
/ 28 октября 2008

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

1 голос
/ 28 октября 2008
0 голосов
/ 15 сентября 2018

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

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


}
0 голосов
/ 15 марта 2015

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

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