前两天做一个项目的时候,由于页面没有限制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. EOutOfResources EConvertError is not a valid integer value Unable to insert a line

    is not a valid integer value???project Teclaser_Single.exe raised exception class EOutOfResources wi ...

  2. Spark sql ---JSON

    介绍Spark SQL的JSON支持,这是我们在Databricks中开发的一个功能,可以在Spark中更容易查询和创建JSON数据.随着网络和移动应用程序的普及,JSON已经成为Web服务API以及 ...

  3. golang 标准库间依赖的可视化展示

    简介 国庆看完 << Go 语言圣经 >>,总想做点什么,来加深下印象.以可视化的方式展示 golang 标准库之间的依赖,可能是一个比较好的切入点.做之前,简单搜了下相关的内 ...

  4. C# 使用FileUpload控件上传图片,将文件转换成二进制进行存储与读取

    状况描述: 需要上传文件,但是不想要保存到实体路径下,便可以用该功能来实现. 效果图: 点击[Upload]按钮,上传文件到数据库: 点击[Preview],预览文件: 具体实现: 前台: <t ...

  5. PE文件格式详解,第二讲,NT头文件格式,以及文件头格式

    PE文件格式详解,第二讲,NT头文件格式,以及文件头格式 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) PS:本篇博客 ...

  6. Cmder 软件中修改λ符号方法

    以前的版本 网上都有,我就不介绍了,  只介绍现在的 1. 打开Cmder软件安装位置 2. 打开vendor文件夹 profile.ps1文件 3. 找到第77行  Write-Host " ...

  7. C#用SerialPort实现串口通讯

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  8. UpdatePanel控件的使用和局部刷新

    http://www.cnblogs.com/baiefjg/archive/2009/06/14/1502813.html

  9. commons-pool与commons-pool2连接池

    commons-pool和commons-pool2是用来建立对象池的框架,提供了一些将对象池化必须要实现的接口和一些默认动作.对象池化之后可以通过pool的概念去管理其生命周期,例如对象的创建,使用 ...

  10. ActiveMQ——activemq的安装详情,修改密码

    1.安装 下载 http://activemq.apache.org/download-archives.html, [推荐]ActiveMQ 5.13.4 Release与jdk1.7搭配(其它版本 ...