前两天做一个项目的时候,由于页面没有限制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按字节长度限制输入的更多相关文章

  1. js校验输入字符串的字节长度

    //检查输入字符串字节长度 function fucCheckLength(strTemp) { var i,sum; sum=0; var length = strTemp.length ; for ...

  2. WPF TextBox 一些设置技巧

    WPF TextBox 一些设置技巧 运行环境:Win10 x64, NetFrameWork 4.8, 作者:乌龙哈里,日期:2019-05-01 参考: 章节: 取消输入法 输入方式设定为Over ...

  3. WPF TextBox PreviewTextInput handle IME (chinese)

    今天调试自己写的WPF的Behavior, 是关于TextBox只能输入数据或者小数点的. 发现有个问题, 就是英文IME下字母等等都能过滤, 但是一旦切换到中文输入法, 就会发现在OnPreview ...

  4. 请问utf-8的中文是一个汉字占三个字节长度吗?

    这是个好问题,可以当作一个笔试题.先从字符编码讲起. 1.美国人首先对其英文字符进行了编码,也就是最早的ascii码,用一个字节的低7位来表示英文的128个字符,高1位统一为0: 2.后来欧洲人发现尼 ...

  5. C#与JS实现 获取指定字节长度 中英文混合字符串 的方法

    平时在作数据库插入操作时,如果用 INSERT 语句向一个varchar型字段插入内容时,有时会因为插入的内容长度超出规定的长度而报错. 尤其是插入中英文混合字符串时,SQL Server中一般中文要 ...

  6. Java String类型数据的字节长度

    问题描述: 向Oracle数据库中一varchar2(64)类型字段中插入一条String类型数据,程序使用String.length()来进行数据的长度校验,如果数据是纯英文,没有问题,但是如果数据 ...

  7. 计算std:string的字节长度

    如果项目本身是使用 Unicode 字符集和utf8编码,std::string的length(),size()甚至是c的strLen取到的都是字节长度了,比如三个汉字,就是9, 以上情况不满足的话, ...

  8. C++中各种数据类型占据字节长度

    准备校招笔试的时候经常遇到C++某个数据类型占据多少个字节的问题,查阅了下资料,总结如下: 首先罗列一下C++中的数据类型都有哪些: 1.整形:int.long 2.字符型:char.wchar_t ...

  9. js截取指定字节长度的字符串

    默认的截取字符串都是根据字符长度或位置截取的,典型的两个方法是substr和substring. 这样导致的问题是截取同样长度的字符串时,多字节字符(汉字等)和单字节字符(半角英文字母.半角数字)占的 ...

随机推荐

  1. Highway Networks

    一 .Highway Networks 与 Deep Networks 的关系 深层神经网络相比于浅层神经网络具有更好的效果,在很多方面都已经取得了很好的效果,特别是在图像处理方面已经取得了很大的突破 ...

  2. vim与sublime,程序员的屠龙刀和倚天剑

    对程序员来说,写代码是再熟悉不过的事情了,windows系统自带有记事本软件,能写写小规模的代码,可是代码量大了,它的局限性就暴露得很明显了:没有语法高亮,没有自动提示,不支持项目管理,界面难看-- ...

  3. Elixir游戏服设计五

    在<Elixir游戏服设计一>里提到,按照系统功能划分成app要保证原子性很难, 现在想想也没那么难.保证原子性,无非就是需要某个单点去完成操作.那么选择玩家进程去做原子性工作就可以了. ...

  4. c#使用GDI+简单绘图

    private void button2_Click(object sender, EventArgs e) { Bitmap image = new Bitmap(200, 200); Graphi ...

  5. Ricequant-米筐金工-估值因子

    Ricequant米筐金工--因子分析 作者:戴宇.小湖 上一篇介绍了单因子检验是因子分析前重要的一个步骤,是构建因子库.建立因子模型的基础,这篇报告首先对常见估值因子进行初步的检验. 第一篇.估值因 ...

  6. 从零开始搭建框架SSM+Redis+Mysql(二)之MAVEN项目搭建

    从零开始搭建框架SSM+Redis+Mysql(二)之MAVEN项目搭建 废话不说,直接撸步骤!!! 1.创建主项目:ncc-parent 选择maven创建项目,注意在创建项目中,packing选择 ...

  7. ASP.NET没有魔法——ASP.NET MVC IoC

    之前的文章介绍了MVC如何通过ControllerFactory及ControllerActivator创建Controller,而Controller又是如何通过ControllerBase这个模板 ...

  8. win10 uwp 绑定密码

    win10 下,密码框无法绑定到ViewModel,Password是不可以绑定. 我们可以自己使用简单方法去绑定 我们之前在WPF 使用绑定密码框,我写了一篇,关于如何绑定,我提供一个我自己试了可以 ...

  9. Python学习笔记(六)

    Python学习笔记(六) Ubuntu重置root密码 Ubuntu 16.4 目录结构 Ubuntu 命令讲解 1. Ubuntu重置root密码 启动系统,显示GRUB选择菜单(如果默认系统启动 ...

  10. zabbix自动截图留档_python版

    1 背景     每个DB Server都有zabbix监控,除了异常情况的报警信息外,也会在日检.周检.月检等工作中用到zabbix的监控数据,对zabbix监控数据会做两种处理:1 数据分析(环比 ...