前两天做一个项目的时候,由于页面没有限制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,疏忽了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://HdhCmsTestcnblogs测试数据/ZXdeveloper/archive/2017/11/07/7798943.html
dy("nrwz");
查看更多关于WPF TextBox实现按字节长度限制输入功能的详细内容...