WPF TextBox实现按字节长度限制输入功能
前两天做一个项目的时候,由于页面没有限制textbox的输入长度,所以,后台直接报错了,超出数据库最大的长度。
数据库的长度是按照字节来计算的,而且不同的编码格式,汉字占用的字节长度又不相同,比如,我们用的是utf8,一个汉字是3个字节,而默认的default,一个汉字是2个字节。
textbox有个maxlength属性,但是这个属性是不太合乎要求的,因为这个长度,是限制了输入的长度,比如设置20,则无论是数字、字母、汉字最大的长度都是20个,但是,对于数据库来说,长度却不相同了,所以,不能使用这个属性。
为了,统一解决下这个问题,所以给textbox写了附加属性。
一、想要的效果
用了附加属性,想达到一个什么效果呢,就是像设置maxlength一样,一旦到了数据库的字节长度,就不再能输入了。
因此,最开始想找一个限制输入的属性,可惜我学的太浅薄,没有找到相关的属性,因此,最后在同事的提醒下,可以记录上一次的内容,然后,如果超长,就用上一次的内容进行赋值
二、附加属性
既然要用附加属性,并且方便使用,那肯定要给开发者暴露出来至少两个:maxbytelength用来设置最大的字节数,encodemodel用来设置编码格式
encodemodel是用menu类型来做的,方便使用时直接敲内容
本来上面是直接想用encoding来做的,奈何它是抽象类,只好,写个方法进行了一部转化,并且把encoding类型的属性进行private。
大致上也就是这么一个思路,下面上代码,给需要的人使用。
public class maxbyteattachedproperty : dependencyobject { public enum encode { default, ascii, utf8, utf32, utf7, bigendianunicode, unicode } private static string getpretext(dependencyobject obj) { return (string)obj.getvalue(pretextproperty); } private static void setpretext(dependencyobject obj, string value) { obj.setvalue(pretextproperty, value); } // using a dependencyproperty as the backing store for pretext. this enables animation, styling, binding, etc... private static readonly dependencyproperty pretextproperty = dependencyproperty.registerattached("pretext", typeof(string), typeof(maxbyteattachedproperty), new propertymetadata("")); public static int getmaxbytelength(dependencyobject obj) { return (int)obj.getvalue(maxbytelengthproperty); } public static void setmaxbytelength(dependencyobject obj, int value) { obj.setvalue(maxbytelengthproperty, value); } // using a dependencyproperty as the backing store for maxbytelength. this enables animation, styling, binding, etc... public static readonly dependencyproperty maxbytelengthproperty = dependencyproperty.registerattached("maxbytelength", typeof(int), typeof(maxbyteattachedproperty), new propertymetadata(ontextboxpropertychanged)); private static void ontextboxpropertychanged(dependencyobject d, dependencypropertychangedeventargs e) { textbox tb = d as textbox; if (tb == null) { return; } tb.textchanged += tb_textchanged; } private static void tb_textchanged(object sender, textchangedeventargs e) { textbox tb = sender as textbox; if (isoutmaxbytelength(tb.text, tb)) { tb.text = getpretext(tb); tb.select(tb.text.length, 0); return; } } public static encode getencodemodel(dependencyobject obj) { return (encode)obj.getvalue(encodemodelproperty); } public static void setencodemodel(dependencyobject obj, encode value) { obj.setvalue(encodemodelproperty, value); } // using a dependencyproperty as the backing store for encodem. this enables animation, styling, binding, etc... public static readonly dependencyproperty encodemodelproperty = dependencyproperty.registerattached("encodemodel", typeof(encode), typeof(maxbyteattachedproperty), new propertymetadata(encode.utf8, onencodemodelchanged)); private static void onencodemodelchanged(dependencyobject d, dependencypropertychangedeventargs e) { setem(d, getencodemodel(d)); } private static encoding getencodingmodel(dependencyobject obj) { return (encoding)obj.getvalue(encodingmodelproperty); } private static void setencodingmodel(dependencyobject obj, encoding value) { obj.setvalue(encodingmodelproperty, value); } // using a dependencyproperty as the backing store for encodingmodel. this enables animation, styling, binding, etc... private static readonly dependencyproperty encodingmodelproperty = dependencyproperty.registerattached("encodingmodel", typeof(encoding), typeof(maxbyteattachedproperty), new propertymetadata(encoding.utf8)); private static void setem(dependencyobject obj, encode e) { switch (e) { case encode.default: setencodingmodel(obj, encoding.default); break; case encode.ascii: setencodingmodel(obj, encoding.ascii); break; case encode.utf8: setencodingmodel(obj, encoding.utf8); break; case encode.utf32: setencodingmodel(obj, encoding.utf32); break; case encode.utf7: setencodingmodel(obj, encoding.utf7); break; case encode.bigendianunicode: setencodingmodel(obj, encoding.bigendianunicode); break; case encode.unicode: setencodingmodel(obj, encoding.unicode); break; default: break; } } private static bool isoutmaxbytelength(string txt, dependencyobject obj) { int txtlength = getencodingmodel(obj).getbytes(txt).length;//文本长度 if (getmaxbytelength(obj) >= txtlength) { setpretext(obj, txt); return false; } return true; } }
使用方法如下:
maxbytelength是必须设置的没有进行默认,encodemodel可以不设置但是由于是我们自己用,所以默认是utf8,可以自行修改代码,按照你们公司的编码格式,这样也就不用赋值了。
代码已修正,感谢presia发现的bug,疏忽了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。