DevExpress控件中TextEdit的MaxLength属性,限制的是字符数。
而在日常开发过程中,我们在TextEdit中输入的字符需要插入到数据库中,而数据库中的字段是字节数,也就是说一个中文汉字是一个字符,但是是两个字
节,当MaxLength属性限制30时,可以输入30个汉字,但是数据库中只让输入15个汉字或者是30个字符,这样验证起来比较的麻烦。
我的想法是扩展一个属性MaxByteLength,功能和MaxLength一样,但其限制的是字节数,这样开发数据库程序起来就比较简单。
但是我在重写的时候却出现了问题:
1、我继承自System.Windows.Forms.TextBox,然后重写protected override void
WndProc(ref System.Windows.Forms.Message
m)方法,很顺利,能实现上述功能的MaxByteLength属性。
2、我继承自DevExpress.XtraEditors.TextEdit,然后重写protected override void
WndProc(ref Message
msg)方法,不能通过,跟踪发现,同样重写这两个方法,但是它们的Message确实不一样的,继承自
DevExpress.XtraEditors.TextEdit得到的Message,没有什么规律。所以无法完成以上功能。
希望路过的高手,帮忙解决一下。
Thanks!
附TextBox实现的代码【转载自http://www.cnblogs.com/lemony/archive/2007/04/10/707474.html】:
public partial class TextEditComponent : System.Windows.Forms.TextBox
{
public TextEditComponent()
{
InitializeComponent();
}
public TextEditComponent(IContainer container)
{
container.Add(this);
InitializeComponent();
}
private const int WM_CONTEXTMENU = 0x007b;//右键菜单消息
private const int WM_CHAR = 0x0102; //输入字符消息(键盘输入的,输入法输入的好像不是这个消息)
private const int WM_CUT = 0x0300; //程序发送此消息给一个编辑框或combobox来删除当前选择的文本
private const int WM_COPY = 0x0301; //程序发送此消息给一个编辑框或combobox来复制当前选择的文本到剪贴板
private const int WM_PASTE = 0x0302; //程序发送此消息给editcontrol或combobox从剪贴板中得到数据
private const int WM_CLEAR = 0x0303; //程序发送此消息给editcontrol或combobox清除当前选择的内容;
private const int WM_UNDO = 0x0304; //程序发送此消息给editcontrol或combobox撤消最后一次操作
#region 属性
private int m_MaxByteLength = 0;
[Description("获取或设置用户可在文本框控件中键入或粘贴的最大字节数。0 为允许无限长度。")]
/// <summary>
/// 获取或设置用户可在文本框控件中键入或粘贴的最大字节数。0 为允许无限长度。
/// </summary>
public int MaxByteLength
{
get { return m_MaxByteLength; }
set { m_MaxByteLength = value; }
}
#endregion
/// <summary>
/// 重写 WndProc
/// </summary>
protected override void WndProc(ref System.Windows.Forms.Message m)
{
//如果该属性没有设置,则允许输入
if (m_MaxByteLength == 0)
{
base.WndProc(ref m);
return;
}
switch (m.Msg)
{
case WM_CHAR:
int i = (int)m.WParam;
bool isBack = (i == (int)System.Windows.Forms.Keys.Back);
bool isDelete = (i == (int)System.Windows.Forms.Keys.Delete);//实际上这是一个"."键
bool isCtr = (i == 24) || (i == 22) || (i == 26) || (i == 3);
if (isBack || isDelete || isCtr)
{
//控制键不作处理
}
else
{
char c = (char)i;
if (CheckByteLengthFlow(c.ToString()))
{
break;
}
}
base.WndProc(ref m);
break;
case WM_PASTE:
System.Windows.Forms.IDataObject iData = System.Windows.Forms.Clipboard.GetDataObject();//取剪贴板对象
if (iData.GetDataPresent(System.Windows.Forms.DataFormats.Text)) //判断是否是Text
{
string text = (string)iData.GetData(System.Windows.Forms.DataFormats.Text);//取数据
if (CheckByteLengthFlow(text))
{
m.Result = (IntPtr)0;//不可以粘贴
break;
}
}
base.WndProc(ref m);
break;
default:
base.WndProc(ref m);
break;
}
}
/// <summary>
/// 判断即将输入的文本长度是否溢出
/// </summary>
/// <param name="text">文本</param>
/// <returns>是否溢出</returns>
private bool CheckByteLengthFlow(string text)
{
int len = GetByteLength(text); //输入的字符的长度
int tlen = GetByteLength(this.Text); //文本框原有文本的长度
int slen = GetByteLength(this.SelectedText); //文本框选中文本的长度
return (m_MaxByteLength < (tlen - slen + len));
}
/// <summary>
/// 计算文本字节长度,区分多字节字符
/// </summary>
/// <param name="text">文本</param>
/// <returns>文本字节长度</returns>
private int GetByteLength(string text)
{
return System.Text.Encoding.Default.GetBytes(text).Length;
}
}
提供一个通用的方法,解决你的问题.
http://www.cnblogs.com/winzheng/archive/2009/03/04/1402721.html
如有问题,请留言.