最近看到一些关于TextBox中限制只允许输入数字的博文,结合笔者前段时间修改完善的开源数值文框TNumEditBox控件,介绍一个解决方法。
在定制的TextBox控件中,如果只允许输入数字,需要考虑如下三种情况:
- 正常按键输入的字符,包括西文、中文字符等
- 通过键盘快捷键方式贴入的文本,即Ctrl+V操作
- 通过上下文关联菜单的Mouse操作贴入的文本,即”粘贴“操作
在探讨的同类文章中,多数只考虑了第1种情况,忽略得了第2、3种常见的操作。本文探讨的处理方法核心思路是重载事件OnKeyPress()和两个法ProcessCmdKey()与WndProc(),并把Ctrl+V、Mouse Paste操作统一到键盘录入操作中,从而在OnKeyPress()屏蔽掉非数字键。
1、重载键盘事件OnKeyPress()
键盘输入的字符可以通过重载TextBox控件的OnKeyPress()事件处理,见如下代码:
2、重载命令键处理方法ProcessCmdKey()
可以在ProcessCmdKey中捕获快捷键Ctrl+V操作。首先要清楚当前的选择文本,然后读取剪切板ClipBoard中的内容,最后通过模拟键盘输入的方式”输入“ClipBoard的内容。需要指出,在ProcessCmdKey()方法中不能使用静态方法SendKeys.Send(),但可以通过控件的WndProc()方法发送字符消息以达到模拟键盘录入的目的。见如下代码。
3、重载消息处理方法WndProc()
可以在定制TextBox控件中创建无内容的上下文菜单对象,从而屏蔽该菜单,方法是在定制控件的构造函数中增加如下代码
4、消除选择ClearSelection()、删除字符DeleteText()
在前面代码中,有两个函数必须分析。其中,函数ClearSelection()用以清除当前的选择文本,即清除this.SeledtedText;函数DeleteText()则删除当前字符。注意其中的技巧,就是转换Delete键操作为BackSpace操作。此外,DeleteText()函数还需要确定当前的this.SelectionStart值。具体代码如下:
、结语
上述内容是从笔者的开源数值型数据编辑控件TNumEditBox中修改删减来的,该控件考虑的情况比只允许数字输入要复杂得多,感兴趣者可以参考并指正。需要指出,TNumEditBox的核心思路来自免费的Delphi控件PBNumEdit和开源的C#控件BANumEdit。作为回报,笔者也将TNumEditBox开源并发布到CodeProject。