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,疏忽了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • WPF TextBox水印效果制作方法详解

    一种自以为是的方式: 本来只是想简单的做个水印效果,在文本框内容为空的时候提示用户输入,这种需求挺常见.网上一搜 都是丢给你你一大段xaml代码.用c#代码实现我是不倾向了 既然用wpf就得Xaml啊.首先我想到的是template嘛 wpf到处离不开template .我想到的是一个border 套一个textblock嘛 然后让文本内容通过templateBinding到Text嘛 搞得不亦乐乎 ,并且也确实很快就达到了我要的效果: <TextBox> <TextBox.Templa

  • WPF TextBox和PasswordBox添加水印

    本文实例为大家分享TextBox和PasswordBox加水印的方法,供大家参考,具体内容如下 Textbox加水印 Textbox加水印,需要一个VisualBrush和触发器验证Text是否为空,在空的时候设置背景的Brush就可以实现水印效果. <TextBox Name="txtBoxName" Width="120" Height="23"> <TextBox.Resources> <VisualBrush

  • WPF TextBox实现按字节长度限制输入功能

    前两天做一个项目的时候,由于页面没有限制TextBox的输入长度,所以,后台直接报错了,超出数据库最大的长度. 数据库的长度是按照字节来计算的,而且不同的编码格式,汉字占用的字节长度又不相同,比如,我们用的是UTF8,一个汉字是3个字节,而默认的Default,一个汉字是2个字节. TextBox有个MaxLength属性,但是这个属性是不太合乎要求的,因为这个长度,是限制了输入的长度,比如设置20,则无论是数字.字母.汉字最大的长度都是20个,但是,对于数据库来说,长度却不相同了,所以,不能使

  • IOS textField限制字节长度

    OC语言中,NSString类型的字符串,视英文字母和汉字都为一个长度(string.length把一个汉字也当做一个长度),而实际上,一个英文字母只占用1个字节,一个汉字占用2个字节. 有时又有需求,需要限定字节数目,而不是内容个数,就需要通过一些方法获取到字符串的字节数.比如,限定10个字节,则最多可以输入10个英文字母,或者5个汉字. 监听textField的长度变化,就需要设置textField的代理. 但是有个bug,监听内容变化的代理方法 - (BOOL)textField:(UIT

  • Javascript 字符串字节长度计算函数代码与效率分析(for VS 正则)

    先看看一下两段代码吧,它们分别用for循环和正则表达式来检测字符串的字节长度: for循环检测字符串的字节长度方法一: 复制代码 代码如下: var lenFor = function(str){ var byteLen=0,len=str.length; if(str){ for(var i=0; i<len; i++){ if(str.charCodeAt(i)>255){ byteLen += 2; } else{ byteLen++; } } return byteLen; } els

  • Node.js实用代码段之获取Buffer对象字节长度

    我们知道Node.js框架下的Buffer对象能够对二进制数据提供很好的支持,那么获取一个Buffer对象真实的字节长度则是必须要用到的功能了.Node.js框架为开发人员提供了一个Buffer.byteLength()方法,下面我们借助一个官方文档提供的例程向读者演示一下该方法的使用过程. 本例ch04.buffer-byteLength.js主要代码如下: /** * ch04.buffer-byteLength.js */ console.info("------Buffer.byteLe

  • python读取指定字节长度的文本方法

    软件版本 Python 2.7.13; Win 10 场景描述 1.使用python读取指定长度的文本: 2.使用python读取某一范围内的文本. Python代码 test.txt文本内包含的字符串为"AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD",A,B,C,D均为8个 # -*- coding:utf-8 -*- text_file = r"test.txt" # open() f = open(text_file, "r&qu

  • iOS高仿微信表情输入功能代码分享

    最近项目需求,要实现一个类似微信的的表情输入,于是把微信的表情扒拉出来,实现了一把.可以从这里下载源码.看起来表情输入没有多少东西,不外乎就是用NSTextAttachment来实现图文混排,结果在实现的过程中遇到了很多小问题,接下来会一一介绍遇到过的坑.先上一张效果图: 一.实现表情选择View(WKExpressionView) 具体的实现就不细说了,主要功能就是点击表情时,将对应表情的图片名称通知给delegate. 二.实现表情textView(WKExpressionTextView)

  • js实现Select下拉框具有输入功能的方法

    本文实例讲述了js实现Select下拉框具有输入功能的方法.分享给大家供大家参考.具体实现方法如下: 实现方法一 复制代码 代码如下: <HTML> <HEAD> <META http-equiv='Content-Type' content='text/html; charset=gb2312'> <TITLE>js实现可输入的下拉框</TITLE> </HEAD> <BODY> <div style="

  • JAVA编程实现随机生成指定长度的密码功能【大小写和数字组合】

    本文实例讲述了JAVA编程实现随机生成指定长度的密码功能.分享给大家供大家参考,具体如下: import java.util.Random; public class PassWordCreate { /** * 获得密码 * @param len 密码长度 * @return */ public String createPassWord(int len){ int random = this.createRandomInt(); return this.createPassWord(rand

  • 为textView添加语音输入功能的实例代码(集成讯飞语音识别)

    非常感谢大家利用自己宝贵的时间来阅读我的文章 , 今天给大家带来的是一个集成讯飞语音识别功能的小demo,为textview添加一个语音输入的功能,相信在这个智能化趋势的大环境的下,很多人能用得到这个功能.如果需要的话希望能帮到你 , 当然, 有任何不妥的地方 欢迎指正. 先上demo --->XunFeiDemo 效果展示: 功能实现,sdk中提供了两种方式,一种是带界面的语音识别,有一个识别语音的动画的界面效果.另一种是无界面的.我这里使用的是带界面的,不带界面的自己可以去看一下,大同小异

  • Python使用tkinter库实现文本显示用户输入功能示例

    本文实例讲述了Python使用tkinter库实现文本显示用户输入功能.分享给大家供大家参考,具体如下: #coding:utf-8 from Tkinter import * class App: def __init__(self,root): #定义帧 frame = Frame(root) frame.pack() self.frame = frame w = Label(frame,text = "calculator") w.pack() self.newinput() #

随机推荐