Visual C++의 Edit Control은 리소스 편집기에서 Number 속성으로 숫자입력창을 쉽게 만들 수 있었습니다.
그런데 WPF의 TextBox에는 상응하는 속성이 없더군요.
ValidationRule을 이용하여 올바른 입력을 유도하라는 의도 같습니다만 불편한건 불편한거죠.
http://karlhulme.wordpress.com/2007/02/15/masking-input-to-a-wpf-textbox/
검색해보니 위 링크의 해결책이 가장 많이 사용되는 것 같더군요.
하지만 다음과 같은 2가지 문제가 있었습니다.
1. Spacebar, Delete, Backspace 등을 처리하지 못합니다.
- 공백 문자등에 대해서는 PreviewTextInput 이벤트가 발생하지 않더군요.
2. 음수 및 소수를 처리하지 못합니다.
- 새로 입력되는 문자(또는 문자열)가 숫자인지만을 처리하는 방식이기 때문에 문자열 전체를 놓고 파악해야 하는 음수, 소수을 처리하지 못합니다.
그래서 다음과 같이 처리했습니다.
- 진입점은 TextChanged 이벤트 핸들러로 할당 (keyboard 입력, copy&paste, drag&drop 모두 처리 가능)
- 숫자 유효성은 문자열 전체에 대해 int, double 등의 TryParse() static 함수 사용 (int, uint, double 등의 자료형 선택으로 정수, 음수, 소수 등 입력형식/범위 제한 가능)
- 유효하지 않은 문자열이 입력된 경우 바로 이전의 유효한 문자열을 다시 할당 (문자열을 다시 할당할 경우 TextChanged 이벤트가 다시 발생한다는 점은 좀 거시기)
- 이전 문자열로 되돌릴 경우 유효한 caret 위치 및 선택상태를 유지하기 위해 SelectionChanged 이벤트 핸들러에서 SelectionStart, SelectionLength 프로퍼티값 저장
private void text_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox textBox = sender as TextBox;
double value;
if (double.TryParse(textBox.Text, out value))
{
this.prevText = textBox.Text;
}
else
{
textBox.Text = this.prevText;
textBox.SelectionLength = this.prevSelectionLength;
textBox.SelectionStart = this.prevSelectionStart;
}
}
int prevSelectionStart;
int prevSelectionLength;
private void text_SelectionChanged(object sender, RoutedEventArgs e)
{
TextBox textbox = sender as TextBox;
this.prevSelectionStart = textbox.SelectionStart;
this.prevSelectionLength = textbox.SelectionLength;
}
-------------------------------------위의 글에서 개선.
1. 입력값이 없을때 default 0 처리
2. 입력시 값이 0이면 사라지도록.
3. [ . ] 만 입력 안되도록 막음.
4. N개의 Textbox도 가능 하도록. -> TXT_GotFocus
'VB.net & WPF & C#' 카테고리의 다른 글
VB.net WPF Bitmap -> ImageSource -> ImageBrush (0) | 2016.12.26 |
---|---|
[WPF, vb.net] Textblock - 특정 String Color 주기 (0) | 2016.12.23 |
[C#] 스레드 동기화를 위한 AutoResetEvent와 ManualResetEvent (0) | 2016.11.17 |
Thread속 Loop(for)에서 event 발생 기다리기 : System.Threading.AutoResetEvent (0) | 2016.11.13 |
Call R Script in C# (0) | 2016.10.09 |