본문 바로가기
[ Program ]/C#

[C# SOURCE]텍스트 박스로 숫자 또는 일부의 문자 밖에 입력할 수 없게 하려면

by 관이119 2012. 9. 18.

텍스트 박스로 숫자 또는 일부의 문자 밖에 입력할 수 없게 하려면 ,

System.Windows.Forms.TextBox를 계승한 커스텀 콘트롤을 사용하는 방법이 가장 간편합니다.

 

KeyPress 이벤트등에서 입력을 규제하고 있는 샘플을 잘 보입니다만, 그것으로는「붙여」의 대응을 할 수 없습니다.
적어도, context menu로부터의[붙이기] (은)는, 키의 입력으로부터 배제할 수 있는 것이 아닙니다.
이것을 막기 위해서 TextChanged 이벤트와 병용 하고 있는 샘플도 있습니다만, 그것으로는 어른거림이 생깁니다.

 

어느 디바이스로 입력되려고, 일원으로 배제할 수 있는 기구로 하는 것이 편합니다.
그렇다고 해서 입력 체크를 하지 않아도 좋은 것은 아닙니다.
그러한 의미에서도, 「최종 체크에 일임 한다」라고 하는 선택사항이 있는 일도 잊지 말아 주세요.

 

실장 방법입니다만, 먼저 말씀드린 것처럼 System.Windows.Forms.TextBox 클래스를 계승한 커스텀 콘트롤을 만듭니다.
여기서, WM_CHAR(클라이언트 영역에의 입력) (와)과 WM_PASTE(붙이기) (을)를 포착해, 그에 적합한 처리를 실시하면 좋습니다.
WM_CHAR와 WM_PASTE를 포착하기 위해서, WndProc 메소드를 오버라이드(override) 하고 있습니다.

 

그에 적합한 처리는, WndProc 메소드로 실장하지 않고, 알기 쉽게 하기 위해서, OnChar 메소드와 OnPaste 메소드를 거치고 있습니다.
문자열을 허가할지의 실제의 판정은 HasPermitChars 정적 메소드와 GetPermitedString 정적 메소드로 실장하고 있습니다.

 

샘플이므로, 알기 쉽게 베타에 실장할까하고 생각했습니다만, 조금 범용성을 갖게하고 싶었기 때문에,

PermitChars 프롭퍼티를 마련했습니다.
여기에 격납된 System.Char의 배열이 허가된 문자가 되어, 여기에 등록되지 않은 문자의 입력은 할 수 없게 됩니다.

 

우선은, 커스텀 콘트롤을 실장해 봅시다.

 

//이하의 이름 공간을 임포트 한다
using System.Windows.Forms;

public class MyTextBox : System.Windows.Forms.TextBox {

# region constructor   

public MyTextBox() {
this.PermitChars = new char[] {};
}

#endregion

# region PermitChars 프롭퍼티

private char[] _PermitChars;

public char[] PermitChars {
get {
return this. _PermitChars;
}

set {
this. _PermitChars = value;
}
}

#endregion

# region WndProc 메소드(override)

protected override void WndProc(ref System.Windows.Forms.Message m) {
const int WM_CHAR = 0 x0102;
const int WM_PASTE = 0 x0302;

switch(m.Msg) {
case WM_CHAR:
if ((this.PermitChars ! = null) && (this.PermitChars.Length 0)) {
KeyPressEventArgs eKeyPress = new KeyPressEventArgs((char)(m.WParam.ToInt32()));
this.OnChar(eKeyPress);

if(eKeyPress.Handled) {
return;
}
}
break;
case WM_PASTE:
if ((this.PermitChars ! = null) && (this.PermitChars.Length 0)) {
this.OnPaste(new System.EventArgs());
return;
}
break;
}

base.WndProc(ref m);
}

#endregion

# region OnChar 메소드(virtual)

protected virtual void OnChar(KeyPressEventArgs e) {
if (char.IsControl(e.KeyChar)) {
return;
}

if (! HasPermitChars(e.KeyChar, this.PermitChars)) {
e.Handled = true;
}
}

# endregion

# region OnPaste 메소드(virtual)

protected virtual void OnPaste(System.EventArgs e) {
string stString = Clipboard.GetDataObject(). GetData(System.Windows.Forms.DataFormats.Text). ToString();

if(stString ! = null) {
this.SelectedText = GetPermitedString(stString, this.PermitChars);
}
}

#endregion

# region[S] HasPermitChars 메소드

private static bool HasPermitChars(char chTarget, char[] chPermits) {
foreach(char ch in chPermits) {
if(chTarget == ch) {
return true;
}
}

return false;
}

#endregion

# region[S] GetPermitedString 메소드

private static string GetPermitedString(string stTarget, char[] chPermits) {
string stReturn = string.Empty;

foreach(char chTarget in stTarget) {
if (HasPermitChars(chTarget, chPermits)) {
stReturn += chTarget;
}
}

return stReturn;
}

#endregion

}

 

그리고는, 이 MyTextBox를 폼에 추가해 이하와 같이, 허가하는 문자를 설정하면 좋습니다.

// 0~5의 입력을 허가한다
this.myTextBox1.PermitChars = new char[] {'0', '1', '2', '3', '4', '5'};

댓글