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.PreviewTextInput += Tb_PreviewTextInput;
}
private static void Tb_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
TextBox tb = sender as TextBox;
if (IsOutMaxByteLength(tb.Text, tb))
{
tb.Text = GetPreText(tb);
tb.Select(tb.Text.Length, );
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,疏忽了
WPF TextBox按字节长度限制输入的更多相关文章
- js校验输入字符串的字节长度
//检查输入字符串字节长度 function fucCheckLength(strTemp) { var i,sum; sum=0; var length = strTemp.length ; for ...
- WPF TextBox 一些设置技巧
WPF TextBox 一些设置技巧 运行环境:Win10 x64, NetFrameWork 4.8, 作者:乌龙哈里,日期:2019-05-01 参考: 章节: 取消输入法 输入方式设定为Over ...
- WPF TextBox PreviewTextInput handle IME (chinese)
今天调试自己写的WPF的Behavior, 是关于TextBox只能输入数据或者小数点的. 发现有个问题, 就是英文IME下字母等等都能过滤, 但是一旦切换到中文输入法, 就会发现在OnPreview ...
- 请问utf-8的中文是一个汉字占三个字节长度吗?
这是个好问题,可以当作一个笔试题.先从字符编码讲起. 1.美国人首先对其英文字符进行了编码,也就是最早的ascii码,用一个字节的低7位来表示英文的128个字符,高1位统一为0: 2.后来欧洲人发现尼 ...
- C#与JS实现 获取指定字节长度 中英文混合字符串 的方法
平时在作数据库插入操作时,如果用 INSERT 语句向一个varchar型字段插入内容时,有时会因为插入的内容长度超出规定的长度而报错. 尤其是插入中英文混合字符串时,SQL Server中一般中文要 ...
- Java String类型数据的字节长度
问题描述: 向Oracle数据库中一varchar2(64)类型字段中插入一条String类型数据,程序使用String.length()来进行数据的长度校验,如果数据是纯英文,没有问题,但是如果数据 ...
- 计算std:string的字节长度
如果项目本身是使用 Unicode 字符集和utf8编码,std::string的length(),size()甚至是c的strLen取到的都是字节长度了,比如三个汉字,就是9, 以上情况不满足的话, ...
- C++中各种数据类型占据字节长度
准备校招笔试的时候经常遇到C++某个数据类型占据多少个字节的问题,查阅了下资料,总结如下: 首先罗列一下C++中的数据类型都有哪些: 1.整形:int.long 2.字符型:char.wchar_t ...
- js截取指定字节长度的字符串
默认的截取字符串都是根据字符长度或位置截取的,典型的两个方法是substr和substring. 这样导致的问题是截取同样长度的字符串时,多字节字符(汉字等)和单字节字符(半角英文字母.半角数字)占的 ...
随机推荐
- 如何关闭eclipse对js xml的验证
经常会发现导入一些js框架,eclipse会编译报错 这是eclipse对js的瞎验证,如何解决呢? 关闭eclipse对js,xml的验证即可: 菜单Window - > Preference ...
- Spring Boot Document Part I
最近准备学习Spring Boot 随便翻一下官方的文档 Part I. Spring Boot Documentation Spirng Boot简短介绍,作为接下来内容的导航,可快速预览本章内容. ...
- Naive and Silly Muggles hdu4720
Naive and Silly Muggles Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
- Excel更改单元格格式后无效
问题描述: 比如修改了数据的自定义显示格式(日期显示 yyyy"年"m"月",手机号分段000-0000-0000),应用后发现只有部分生效,或者都不生效,再检 ...
- P60 2.6
import java.util.Scanner; public class Num { public static void main(String[] args) { Scanner input ...
- python的urlparse
urlparse主要是URL的分解和拼接,分析出URL中的各项参数,可以被其他的URL使用. 主要的函数有: 1.urlparse 将URL分解为6个片段,返回一个元组,包括协议.基地址.相对地址等等 ...
- Oracle Database 10g Express Edition系统文件损坏的解决办法
1.检查错误代码:ora-10010 亦或是ora-10003,上网找响应的解决办法: 异常状态:登陆不上 常用的方法解决 (1)进入Oracle命令行模式 (2)Shutdown immedaite ...
- [#1] YCbCr与RGB的转换公式
1 YCbCr简介 YCbCr颜色空间是将RGB颜色空间进行坐标转换后得到的,常用于数字电视系统.Y取值范围:16~235 Cb.Cr的取值范围:16~240 YCbCr经常和YUV混淆.两者的主要差 ...
- 【学习】文本框输入监听事件oninput
真实项目中遇到的,需求是:一个文本框,一个按钮,当文本框输入内容时,按钮可用,当删除内容时,按钮不可用. 刚开始用的focus和blur, $(".pay-text").focus ...
- python 中的enumerate()函数的用法
enumerate函数说明: 函数语法:enumerate(可遍历的对象,索引号开始的值).enumerate(sequence, [start=0]) 功能:将可循环序列sequence以start ...