programing tip

숫자 만 허용하는 텍스트 상자는 어떻게 만듭니 까?

itbloger 2020. 10. 4. 10:38
반응형

숫자 만 허용하는 텍스트 상자는 어떻게 만듭니 까?


정수 값만 허용하려는 텍스트 상자 컨트롤이있는 Windows Forms 앱이 있습니다. 과거에는 KeyPress 이벤트를 오버로드하고 사양에 맞지 않는 문자를 제거하여 이러한 종류의 유효성 검사를 수행했습니다. MaskedTextBox 컨트롤을 살펴 보았지만 정규식으로 작동하거나 다른 컨트롤의 값에 의존 할 수있는보다 일반적인 솔루션을 원합니다.

이상적으로 이것은 숫자가 아닌 문자를 누르면 결과가 생성되지 않거나 사용자에게 잘못된 문자에 대한 피드백을 즉시 제공하는 방식으로 동작합니다.


두 가지 옵션 :

  1. NumericUpDown대신 사용하십시오 . NumericUpDown이 필터링을 수행합니다. 물론 사용자가 키보드의 위쪽 및 아래쪽 화살표를 눌러 현재 값을 늘리거나 줄일 수 있습니다.

  2. 숫자 입력 이외의 것을 방지하려면 적절한 키보드 이벤트를 처리하십시오. 표준 TextBox에서이 두 가지 이벤트 처리기로 성공했습니다.

    private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) &&
            (e.KeyChar != '.'))
        {
                e.Handled = true;
        }
    
        // only allow one decimal point
        if ((e.KeyChar == '.') && ((sender as TextBox).Text.IndexOf('.') > -1))
        {
            e.Handled = true;
        }
    }
    

TextBox에서 소수점 이하 자릿수를 허용하지 않아야하는 경우 '.'검사 (및 이후에 둘 이상의 검사)를 제거 할 수 있습니다 '.'. '-'TextBox가 음수 값을 허용해야하는지 여부를 확인할 수도 있습니다 .

사용자의 자릿수를 제한하려면 다음을 사용하십시오. textBox1.MaxLength = 2; // this will allow the user to enter only 2 digits


한 줄로 작업하는 것이 항상 더 재미 있기 때문에 ...

 private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar);
    }

참고 : 이것은 사용자가이 텍스트 상자에 복사 / 붙여 넣기하는 것을 방지하지 않습니다. 데이터를 삭제하는 안전한 방법은 아닙니다.


컨텍스트 및 사용한 태그에서 .NET C # 앱을 작성하고 있다고 가정합니다. 이 경우 텍스트 변경 이벤트를 구독하고 각 키 입력의 유효성을 검사 할 수 있습니다.

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        if (System.Text.RegularExpressions.Regex.IsMatch(textBox1.Text, "[^0-9]"))
        {
            MessageBox.Show("Please enter only numbers.");
            textBox1.Text = textBox1.Text.Remove(textBox1.Text.Length - 1);
        }
    }

다음은 System.Int32 입력 만 허용하는 표준 TextBox에서 파생 된 간단한 독립 실행 형 Winforms 사용자 지정 컨트롤입니다 (System.Int64 등과 같은 다른 유형에 쉽게 적용 할 수 있음). 복사 / 붙여 넣기 작업과 음수를 지원합니다.

public class Int32TextBox : TextBox
{
    protected override void OnKeyPress(KeyPressEventArgs e)
    {
        base.OnKeyPress(e);

        NumberFormatInfo fi = CultureInfo.CurrentCulture.NumberFormat;

        string c = e.KeyChar.ToString();
        if (char.IsDigit(c, 0))
            return;

        if ((SelectionStart == 0) && (c.Equals(fi.NegativeSign)))
            return;

        // copy/paste
        if ((((int)e.KeyChar == 22) || ((int)e.KeyChar == 3))
            && ((ModifierKeys & Keys.Control) == Keys.Control))
            return;

        if (e.KeyChar == '\b')
            return;

        e.Handled = true;
    }

    protected override void WndProc(ref System.Windows.Forms.Message m)
    {
        const int WM_PASTE = 0x0302;
        if (m.Msg == WM_PASTE)
        {
            string text = Clipboard.GetText();
            if (string.IsNullOrEmpty(text))
                return;

            if ((text.IndexOf('+') >= 0) && (SelectionStart != 0))
                return;

            int i;
            if (!int.TryParse(text, out i)) // change this for other integer types
                return;

            if ((i < 0) && (SelectionStart != 0))
                return;
        }
        base.WndProc(ref m);
    }

2017 업데이트 : 첫 번째 답변에는 몇 가지 문제가 있습니다.

  • 주어진 유형의 정수보다 긴 것을 입력 할 수 있습니다 (예 : 2147483648은 Int32.MaxValue보다 큽니다).
  • 일반적 으로 입력 한 결과대한 실제 유효성 검사가 없습니다 .
  • int32 만 처리하므로 각 유형 (Int64 등)에 대해 특정 TextBox 파생 컨트롤을 작성해야합니다.

그래서 복사 / 붙여 넣기, + 및-기호 등을 지원하는 더 일반적인 다른 버전을 생각해 냈습니다.

public class ValidatingTextBox : TextBox
{
    private string _validText;
    private int _selectionStart;
    private int _selectionEnd;
    private bool _dontProcessMessages;

    public event EventHandler<TextValidatingEventArgs> TextValidating;

    protected virtual void OnTextValidating(object sender, TextValidatingEventArgs e) => TextValidating?.Invoke(sender, e);

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        if (_dontProcessMessages)
            return;

        const int WM_KEYDOWN = 0x100;
        const int WM_ENTERIDLE = 0x121;
        const int VK_DELETE = 0x2e;

        bool delete = m.Msg == WM_KEYDOWN && (int)m.WParam == VK_DELETE;
        if ((m.Msg == WM_KEYDOWN && !delete) || m.Msg == WM_ENTERIDLE)
        {
            DontProcessMessage(() =>
            {
                _validText = Text;
                _selectionStart = SelectionStart;
                _selectionEnd = SelectionLength;
            });
        }

        const int WM_CHAR = 0x102;
        const int WM_PASTE = 0x302;
        if (m.Msg == WM_CHAR || m.Msg == WM_PASTE || delete)
        {
            string newText = null;
            DontProcessMessage(() =>
            {
                newText = Text;
            });

            var e = new TextValidatingEventArgs(newText);
            OnTextValidating(this, e);
            if (e.Cancel)
            {
                DontProcessMessage(() =>
                {
                    Text = _validText;
                    SelectionStart = _selectionStart;
                    SelectionLength = _selectionEnd;
                });
            }
        }
    }

    private void DontProcessMessage(Action action)
    {
        _dontProcessMessages = true;
        try
        {
            action();
        }
        finally
        {
            _dontProcessMessages = false;
        }
    }
}

public class TextValidatingEventArgs : CancelEventArgs
{
    public TextValidatingEventArgs(string newText) => NewText = newText;
    public string NewText { get; }
}

Int32의 경우 다음과 같이 파생 할 수 있습니다.

public class Int32TextBox : ValidatingTextBox
{
    protected override void OnTextValidating(object sender, TextValidatingEventArgs e)
    {
        e.Cancel = !int.TryParse(e.NewText, out int i);
    }
}

또는 파생없이 다음과 같이 새 TextValidating 이벤트를 사용합니다.

var vtb = new ValidatingTextBox();
...
vtb.TextValidating += (sender, e) => e.Cancel = !int.TryParse(e.NewText, out int i);

그러나 좋은 점은 모든 문자열과 유효성 검사 루틴에서 작동한다는 것입니다.


이것이 바로 Validated / Validating 이벤트의 목적입니다.

주제에 대한 MSDN 문서는 다음과 같습니다. http://msdn.microsoft.com/en-us/library/system.windows.forms.control.validating.aspx

TL; DR 버전 : Validating 이벤트에서 .Text 속성을 확인 e.Cancel=True하고 데이터가 유효하지 않은 경우 설정 합니다.

e.Cancel = True로 설정하면 사용자는 필드를 떠날 수 없지만 뭔가 잘못되었다는 피드백을 제공해야합니다. 문제를 나타 내기 위해 상자의 배경색을 밝은 빨간색으로 변경합니다. SystemColors.WindowValidating이 좋은 값으로 호출되면 다시 설정해야 합니다.


MaskedTextBox 사용해보십시오 . 간단한 마스크 형식을 사용하므로 입력을 숫자 나 날짜 등으로 제한 할 수 있습니다.


TextChanged이벤트를 사용할 수 있습니다

private void textBox_BiggerThan_TextChanged(object sender, EventArgs e)
{
    long a;
    if (! long.TryParse(textBox_BiggerThan.Text, out a))
    {
        // If not int clear textbox text or Undo() last operation
        textBox_LessThan.Clear();
    }
}

이것은 유용 할 수 있습니다. 적절한 소수점과 앞의 플러스 또는 마이너스 기호를 포함한 "실제"숫자 값을 허용합니다. 관련 KeyPress 이벤트 내에서 호출하십시오.

       private bool IsOKForDecimalTextBox(char theCharacter, TextBox theTextBox)
    {
        // Only allow control characters, digits, plus and minus signs.
        // Only allow ONE plus sign.
        // Only allow ONE minus sign.
        // Only allow the plus or minus sign as the FIRST character.
        // Only allow ONE decimal point.
        // Do NOT allow decimal point or digits BEFORE any plus or minus sign.

        if (
            !char.IsControl(theCharacter)
            && !char.IsDigit(theCharacter)
            && (theCharacter != '.')
            && (theCharacter != '-')
            && (theCharacter != '+')
        )
        {
            // Then it is NOT a character we want allowed in the text box.
            return false;
        }



        // Only allow one decimal point.
        if (theCharacter == '.'
            && theTextBox.Text.IndexOf('.') > -1)
        {
            // Then there is already a decimal point in the text box.
            return false;
        }

        // Only allow one minus sign.
        if (theCharacter == '-'
            && theTextBox.Text.IndexOf('-') > -1)
        {
            // Then there is already a minus sign in the text box.
            return false;
        }

        // Only allow one plus sign.
        if (theCharacter == '+'
            && theTextBox.Text.IndexOf('+') > -1)
        {
            // Then there is already a plus sign in the text box.
            return false;
        }

        // Only allow one plus sign OR minus sign, but not both.
        if (
            (
                (theCharacter == '-')
                || (theCharacter == '+')
            )
            && 
            (
                (theTextBox.Text.IndexOf('-') > -1)
                ||
                (theTextBox.Text.IndexOf('+') > -1)
            )
            )
        {
            // Then the user is trying to enter a plus or minus sign and
            // there is ALREADY a plus or minus sign in the text box.
            return false;
        }

        // Only allow a minus or plus sign at the first character position.
        if (
            (
                (theCharacter == '-')
                || (theCharacter == '+')
            )
            && theTextBox.SelectionStart != 0
            )
        {
            // Then the user is trying to enter a minus or plus sign at some position 
            // OTHER than the first character position in the text box.
            return false;
        }

        // Only allow digits and decimal point AFTER any existing plus or minus sign
        if  (
                (
                    // Is digit or decimal point
                    char.IsDigit(theCharacter)
                    ||
                    (theCharacter == '.')
                )
                &&
                (
                    // A plus or minus sign EXISTS
                    (theTextBox.Text.IndexOf('-') > -1)
                    ||
                    (theTextBox.Text.IndexOf('+') > -1)
                )
                &&
                    // Attempting to put the character at the beginning of the field.
                    theTextBox.SelectionStart == 0
            )
        {
            // Then the user is trying to enter a digit or decimal point in front of a minus or plus sign.
            return false;
        }

        // Otherwise the character is perfectly fine for a decimal value and the character
        // may indeed be placed at the current insertion position.
        return true;
    }

WinForms에서 누락 된 항목을 완성하기 위해 구성 요소 모음을 작업 해 왔습니다. 여기에 고급 양식이 있습니다.

특히 이것은 Regex TextBox의 클래스입니다.

/// <summary>Represents a Windows text box control that only allows input that matches a regular expression.</summary>
public class RegexTextBox : TextBox
{
    [NonSerialized]
    string lastText;

    /// <summary>A regular expression governing the input allowed in this text field.</summary>
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public virtual Regex Regex { get; set; }

    /// <summary>A regular expression governing the input allowed in this text field.</summary>
    [DefaultValue(null)]
    [Category("Behavior")]
    [Description("Sets the regular expression governing the input allowed for this control.")]
    public virtual string RegexString {
        get {
            return Regex == null ? string.Empty : Regex.ToString();
        }
        set {
            if (string.IsNullOrEmpty(value))
                Regex = null;
            else
                Regex = new Regex(value);
        }
    }

    protected override void OnTextChanged(EventArgs e) {
        if (Regex != null && !Regex.IsMatch(Text)) {
            int pos = SelectionStart - Text.Length + (lastText ?? string.Empty).Length;
            Text = lastText;
            SelectionStart = Math.Max(0, pos);
        }

        lastText = Text;

        base.OnTextChanged(e);
    }
}

단순히 다음과 같은 것을 추가하는 것으로 myNumbericTextBox.RegexString = "^(\\d+|)$";충분합니다.


CodePlex 에서 이것을 위해 뭔가를 만들었습니다 .

TextChanged 이벤트를 가로 채서 작동합니다. 결과가 좋은 숫자이면 저장됩니다. 뭔가 잘못되면 마지막 좋은 값이 복원됩니다. 소스가 너무 커서 여기에 게시 할 수 없지만 여기 에이 논리의 핵심을 처리하는 클래스에 대한 링크가 있습니다.


이 코드를 텍스트 상자에 사용하십시오.

private void textBox1_TextChanged(object sender, EventArgs e)
{

    double parsedValue;

    if (!double.TryParse(textBox1.Text, out parsedValue))
    {
        textBox1.Text = "";
    }
}

텍스트 상자의 정의가있는 웹 페이지에서 onkeypress숫자 만 허용 하는 이벤트를 추가 할 수 있습니다 . 메시지를 표시하지 않지만 잘못된 입력을 방지합니다. 그것은 나를 위해 일했고 사용자는 숫자 이외의 것을 입력 할 수 없었습니다.

<asp:TextBox runat="server" ID="txtFrom"
     onkeypress="if(isNaN(String.fromCharCode(event.keyCode))) return false;">

NumericUpDown컨트롤을 사용하고 추악한 위아래 버튼 가시성을으로 설정하십시오 false.

numericUpDown1.Controls[0].Visible = false;

NumericUpDown 실제로는 '회전 상자'(위쪽 버튼), 텍스트 상자 및이를 모두 함께 확인하고 엉키는 코드를 포함하는 컨트롤 모음입니다.

마킹 :

YourNumericUpDown.Controls[0].visible = false 

기본 코드를 활성 상태로 유지하면서 버튼을 숨 깁니다.

명백한 해결책은 아니지만 간단하고 효과적입니다. .Controls[1]대신 그렇게하려면 텍스트 상자 부분을 숨 깁니다.


당신은 사용할 수 의 TextChanged / 키 누르기 이벤트 번호를 필터에 정규식을 사용하고 어떤 조치를 취할 수 있습니다.


private void txt3_KeyPress(object sender, KeyPressEventArgs e)
{
    for (int h = 58; h <= 127; h++)
    {
        if (e.KeyChar == h)             //58 to 127 is alphabets tat will be         blocked
        {
            e.Handled = true;
        }
    }
    for(int k=32;k<=47;k++)
    {
        if (e.KeyChar == k)              //32 to 47 are special characters tat will 
        {                                  be blocked
            e.Handled = true;
        }
    }
}

이것은 매우 간단합니다


WinForm의 입력 처리 살펴보기

텍스트 상자에 ProcessCmdKey 및 OnKeyPress 이벤트를 사용하는 솔루션을 게시했습니다. 주석은 Regex를 사용하여 키 누르기를 확인하고 적절하게 차단 / 허용하는 방법을 보여줍니다.


안녕하세요, 텍스트 상자의 textchanged 이벤트에서 이와 같은 작업을 수행 할 수 있습니다.

여기에 데모가 있습니다

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        string actualdata = string.Empty;
        char[] entereddata = textBox1.Text.ToCharArray();
        foreach (char aChar in entereddata.AsEnumerable())
        {
            if (Char.IsDigit(aChar))
            {
                actualdata = actualdata + aChar;
                // MessageBox.Show(aChar.ToString());
            }
            else
            {
                MessageBox.Show(aChar + " is not numeric");
                actualdata.Replace(aChar, ' ');
                actualdata.Trim();
            }
        }
        textBox1.Text = actualdata;
    }

이 질문에 대한 현재 답변 중 상당수가 입력 텍스트를 수동으로 구문 분석하는 것 같습니다. 특정 내장 숫자 유형 (예 : int또는 double)을 찾고 있다면 해당 유형의 TryParse메서드에 작업을 위임하지 않는 이유는 무엇입니까? 예를 들면 :

public class IntTextBox : TextBox
{
    string PreviousText = "";
    int BackingResult;

    public IntTextBox()
    {
        TextChanged += IntTextBox_TextChanged;
    }

    public bool HasResult { get; private set; }

    public int Result
    {
        get
        {
            return HasResult ? BackingResult : default(int);
        }
    }

    void IntTextBox_TextChanged(object sender, EventArgs e)
    {
        HasResult = int.TryParse(Text, out BackingResult);

        if (HasResult || string.IsNullOrEmpty(Text))
        {
            // Commit
            PreviousText = Text;
        }
        else
        {
            // Revert
            var changeOffset = Text.Length - PreviousText.Length;
            var previousSelectionStart =
                Math.Max(0, SelectionStart - changeOffset);

            Text = PreviousText;
            SelectionStart = previousSelectionStart;
        }
    }
}

좀 더 일반적인 것을 원하지만 Visual Studio의 디자이너와 여전히 호환되는 경우 :

public class ParsableTextBox : TextBox
{
    TryParser BackingTryParse;
    string PreviousText = "";
    object BackingResult;

    public ParsableTextBox()
        : this(null)
    {
    }

    public ParsableTextBox(TryParser tryParse)
    {
        TryParse = tryParse;

        TextChanged += ParsableTextBox_TextChanged;
    }

    public delegate bool TryParser(string text, out object result);

    public TryParser TryParse
    {
        set
        {
            Enabled = !(ReadOnly = value == null);

            BackingTryParse = value;
        }
    }

    public bool HasResult { get; private set; }

    public object Result
    {
        get
        {
            return GetResult<object>();
        }
    }

    public T GetResult<T>()
    {
        return HasResult ? (T)BackingResult : default(T);
    }

    void ParsableTextBox_TextChanged(object sender, EventArgs e)
    {
        if (BackingTryParse != null)
        {
            HasResult = BackingTryParse(Text, out BackingResult);
        }

        if (HasResult || string.IsNullOrEmpty(Text))
        {
            // Commit
            PreviousText = Text;
        }
        else
        {
            // Revert
            var changeOffset = Text.Length - PreviousText.Length;
            var previousSelectionStart =
                Math.Max(0, SelectionStart - changeOffset);

            Text = PreviousText;
            SelectionStart = previousSelectionStart;
        }
    }
}

마지막으로 완전히 일반적인 것을 원하고 Designer 지원에 신경 쓰지 않는 경우 :

public class ParsableTextBox<T> : TextBox
{
    TryParser BackingTryParse;
    string PreviousText;
    T BackingResult;

    public ParsableTextBox()
        : this(null)
    {
    }

    public ParsableTextBox(TryParser tryParse)
    {
        TryParse = tryParse;

        TextChanged += ParsableTextBox_TextChanged;
    }

    public delegate bool TryParser(string text, out T result);

    public TryParser TryParse
    {
        set
        {
            Enabled = !(ReadOnly = value == null);

            BackingTryParse = value;
        }
    }

    public bool HasResult { get; private set; }

    public T Result
    {
        get
        {
            return HasResult ? BackingResult : default(T);
        }
    }

    void ParsableTextBox_TextChanged(object sender, EventArgs e)
    {
        if (BackingTryParse != null)
        {
            HasResult = BackingTryParse(Text, out BackingResult);
        }

        if (HasResult || string.IsNullOrEmpty(Text))
        {
            // Commit
            PreviousText = Text;
        }
        else
        {
            // Revert
            var changeOffset = Text.Length - PreviousText.Length;
            var previousSelectionStart =
                Math.Max(0, SelectionStart - changeOffset);

            Text = PreviousText;
            SelectionStart = previousSelectionStart;
        }
    }
}

음수를 포함하여 정수와 실수를 모두 허용해야합니다.

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
    // Text
    string text = ((Control) sender).Text;

    // Is Negative Number?
    if (e.KeyChar == '-' && text.Length == 0)
    {
        e.Handled = false;
        return;
    }

    // Is Float Number?
    if (e.KeyChar == '.' && text.Length > 0 && !text.Contains("."))
    {
        e.Handled = false;
        return;
    }

    // Is Digit?
    e.Handled = (!char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar));
}

Fabio Iotti의 답변에 설명 된 접근 방식을 사용하여 더 일반적인 솔루션을 만들었습니다.

public abstract class ValidatedTextBox : TextBox {
    private string m_lastText = string.Empty;
    protected abstract bool IsValid(string text);
    protected sealed override void OnTextChanged(EventArgs e) {
        if (!IsValid(Text)) {
            var pos = SelectionStart - Text.Length + m_lastText.Length;
            Text = m_lastText;
            SelectionStart = Math.Max(0, pos);
        }
        m_lastText = Text;
        base.OnTextChanged(e);
    }
}

모든 중요하지 않은 유효성 검사 동작을 포함하는 "ValidatedTextBox". 남은 일은이 클래스에서 상속하고 필요한 유효성 검사 논리로 "IsValid"메서드를 재정의하는 것입니다. 예를 들어,이 클래스를 사용하면 특정 정규 표현식과 일치하는 문자열 만 허용하는 "RegexedTextBox"를 만들 수 있습니다.

public abstract class RegexedTextBox : ValidatedTextBox {
    private readonly Regex m_regex;
    protected RegexedTextBox(string regExpString) {
        m_regex = new Regex(regExpString);
    }
    protected override bool IsValid(string text) {
        return m_regex.IsMatch(Text);
    }
}

그 후 "RegexedTextBox"클래스에서 상속하여 "PositiveNumberTextBox"및 "PositiveFloatingPointNumberTextBox"컨트롤을 쉽게 만들 수 있습니다.

public sealed class PositiveNumberTextBox : RegexedTextBox {
    public PositiveNumberTextBox() : base(@"^\d*$") { }
}

public sealed class PositiveFloatingPointNumberTextBox : RegexedTextBox {
    public PositiveFloatingPointNumberTextBox()
        : base(@"^(\d+\" + CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator + @")?\d*$") { }
}

죽은자를 깨워서 미안하지만 누군가 나중에 참조 할 때 유용하다고 생각했습니다.

여기에 제가 처리하는 방법이 있습니다. 부동 소수점 숫자를 처리하지만 정수로 쉽게 수정할 수 있습니다.

기본적으로 만 누를 수 0 - 9.

앞에 0 이 하나만있을 수 있습니다 .

다른 모든 문자는 무시되고 커서 위치는 유지됩니다.

    private bool _myTextBoxChanging = false;

    private void myTextBox_TextChanged(object sender, EventArgs e)
    {
        validateText(myTextBox);
    }

    private void validateText(TextBox box)
    {
        // stop multiple changes;
        if (_myTextBoxChanging)
            return;
        _myTextBoxChanging = true;

        string text = box.Text;
        if (text == "")
            return;
        string validText = "";
        bool hasPeriod = false;
        int pos = box.SelectionStart;
        for (int i = 0; i < text.Length; i++ )
        {
            bool badChar = false;
            char s = text[i];
            if (s == '.')
            {
                if (hasPeriod)
                    badChar = true;
                else
                    hasPeriod = true;
            }
            else if (s < '0' || s > '9')
                badChar = true;

            if (!badChar)
                validText += s;
            else
            {
                if (i <= pos)
                    pos--;
            }
        }

        // trim starting 00s
        while (validText.Length >= 2 && validText[0] == '0')
        {
            if (validText[1] != '.')
            {
                validText = validText.Substring(1);
                if (pos < 2)
                    pos--;
            }
            else
                break;
        }

        if (pos > validText.Length)
            pos = validText.Length;
        box.Text = validText;
        box.SelectionStart = pos;
        _myTextBoxChanging = false;
    }

다음은 빠르게 수정 된 int 버전입니다.

    private void validateText(TextBox box)
    {
        // stop multiple changes;
        if (_myTextBoxChanging)
            return;
        _myTextBoxChanging = true;

        string text = box.Text;
        if (text == "")
            return;
        string validText = "";
        int pos = box.SelectionStart;
        for (int i = 0; i < text.Length; i++ )
        {
            char s = text[i];
            if (s < '0' || s > '9')
            {
                if (i <= pos)
                    pos--;
            }
            else
                validText += s;
        }

        // trim starting 00s 
        while (validText.Length >= 2 && validText.StartsWith("00")) 
        { 
            validText = validText.Substring(1); 
            if (pos < 2) 
                pos--; 
        } 

        if (pos > validText.Length)
            pos = validText.Length;
        box.Text = validText;
        box.SelectionStart = pos;
        _myTextBoxChanging = false;
    }

KeyDown 이벤트에서 처리합니다.

void TextBox_KeyDown(object sender, KeyEventArgs e)
        {
            char c = Convert.ToChar(e.PlatformKeyCode);
            if (!char.IsDigit(c))
            {
                e.Handled = true;
            }
        }

이것은 복사 및 붙여 넣기, 드래그 앤 드롭, 키 다운, 오버플로 방지 및 매우 간단합니다.

public partial class IntegerBox : TextBox 
{
    public IntegerBox()
    {
        InitializeComponent();
        this.Text = 0.ToString();
    }

    protected override void OnPaint(PaintEventArgs pe)
    {
        base.OnPaint(pe);
    }

    private String originalValue = 0.ToString();

    private void Integerbox_KeyPress(object sender, KeyPressEventArgs e)
    {
        originalValue = this.Text;
    }

    private void Integerbox_TextChanged(object sender, EventArgs e)
    {
        try
        {
            if(String.IsNullOrWhiteSpace(this.Text))
            {
                this.Text = 0.ToString();
            }
            this.Text = Convert.ToInt64(this.Text.Trim()).ToString();
        }
        catch (System.OverflowException)
        {
            MessageBox.Show("Value entered is to large max value: " + Int64.MaxValue.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            this.Text = originalValue;
        }
        catch (System.FormatException)
        {                
            this.Text = originalValue;
        }
        catch (System.Exception ex)
        {
            this.Text = originalValue;
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK , MessageBoxIcon.Error);
        }
    }       
}

사용자가 잘못된 텍스트를 TextBox.

이를 제한하려면 아래 코드를 따르십시오.

private void ultraTextEditor1_TextChanged(object sender, EventArgs e)
{
    string append="";
    foreach (char c in ultraTextEditor1.Text)
    {
        if ((!Char.IsNumber(c)) && (c != Convert.ToChar(Keys.Back)))
        {

        }
        else
        {
            append += c;
        }
    }

    ultraTextEditor1.Text = append;
}   

나는 또한 텍스트 상자의 숫자 만 확인하는 가장 좋은 방법을 찾고 있었고 키 누름 문제는 오른쪽 클릭 또는 클립 보드로 복사 붙여 넣기를 지원하지 않기 때문에 커서가 텍스트 필드를 떠날 때 유효성을 검사하고 확인하는이 코드를 생각해 냈습니다. 빈 필드. (newguy의 적응 버전)

private void txtFirstValue_MouseLeave(object sender, EventArgs e)
{
    int num;
    bool isNum = int.TryParse(txtFirstValue.Text.Trim(), out num);

    if (!isNum && txtFirstValue.Text != String.Empty)
    {
        MessageBox.Show("The First Value You Entered Is Not a Number, Please Try Again", "Invalid Value Detected", MessageBoxButtons.OK, MessageBoxIcon.Error);
        txtFirstValue.Clear();
    }
}

이것은 내 앞치마입니다.

  1. linq 사용 (쉬운 필터 수정)
  2. 증명 코드 복사 / 붙여 넣기
  3. 금지 된 문자를 누를 때 캐럿 위치를 유지합니다.
  4. 왼쪽 0을 허용합니다.
  5. 및 모든 크기 번호

    private void numeroCuenta_TextChanged(object sender, EventArgs e)
    {
        string org = numeroCuenta.Text;
        string formated = string.Concat(org.Where(c => (c >= '0' && c <= '9')));
        if (formated != org)
        {
            int s = numeroCuenta.SelectionStart;
            if (s > 0 && formated.Length > s && org[s - 1] != formated[s - 1]) s--;
            numeroCuenta.Text = formated;
            numeroCuenta.SelectionStart = s;
        }
    }
    

int Number;
bool isNumber;
isNumber = int32.TryPase(textbox1.text, out Number);

if (!isNumber)
{ 
    (code if not an integer);
}
else
{
    (code if an integer);
}

3 솔루션

1)

//Add to the textbox's KeyPress event
//using Regex for number only textBox

private void txtBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (!System.Text.RegularExpressions.Regex.IsMatch(e.KeyChar.ToString(), "\\d+"))
e.Handled = true;
}

2) msdn의 또 다른 솔루션

// Boolean flag used to determine when a character other than a number is entered.
private bool nonNumberEntered = false;
// Handle the KeyDown event to determine the type of character entered into the     control.
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
// Initialize the flag to false.
nonNumberEntered = false;
// Determine whether the keystroke is a number from the top of the keyboard.
if (e.KeyCode < Keys.D0 || e.KeyCode > Keys.D9)
{
    // Determine whether the keystroke is a number from the keypad.
    if (e.KeyCode < Keys.NumPad0 || e.KeyCode > Keys.NumPad9)
    {
        // Determine whether the keystroke is a backspace.
        if (e.KeyCode != Keys.Back)
        {
            // A non-numerical keystroke was pressed.
            // Set the flag to true and evaluate in KeyPress event.
            nonNumberEntered = true;
        }
    }
}

}

private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
    if (nonNumberEntered == true)
    {
       MessageBox.Show("Please enter number only..."); 
       e.Handled = true;
    }
}

출처 http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress(v=VS.90).aspx

3) using the MaskedTextBox: http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.aspx


In button click you can check text of textbox by for loop:

char[] c = txtGetCustomerId.Text.ToCharArray();
bool IsDigi = true;

for (int i = 0; i < c.Length; i++)
     {
       if (c[i] < '0' || c[i] > '9')
      { IsDigi = false; }
     }
 if (IsDigi)
    { 
     // do something
    }

Simpler answer:

_textBox.TextChanged += delegate(System.Object o, System.EventArgs e)
{
    TextBox _tbox = o as TextBox;
    _tbox.Text = new string(_tbox.Text.Where(c => (char.IsDigit(c)) || (c == '.')).ToArray());
};

참고URL : https://stackoverflow.com/questions/463299/how-do-i-make-a-textbox-that-only-accepts-numbers

반응형