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

 更新时间:2017年11月08日 14:50:33   作者:衆尋  
这篇文章主要为大家详细介绍了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,疏忽了。

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

相关文章

  • 如何在c#中使用Zlib压缩与解压

    如何在c#中使用Zlib压缩与解压

    这篇文章主要介绍了如何在c#中使用Zlib压缩与解压,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-04-04
  • C#微信开发之获取接口调用凭据

    C#微信开发之获取接口调用凭据

    本文主要介绍了C#微信开发之接收 / 返回文本消息原理与实现方法,具有一定的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • C#从前面或后面按指定数量删除字符串

    C#从前面或后面按指定数量删除字符串

    这篇文章介绍了C#从前面或后面按指定数量删除字符串的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • Unity3D开发教程:愤怒的小鸟

    Unity3D开发教程:愤怒的小鸟

    这篇文章详细的讲解了如何从0开发出一个Unity3D的小游戏愤怒的小鸟,本文包含大量的图片与文字描述,也含有大量的源代码,可以让你快速入手,希望本篇文章对你有所帮助
    2021-06-06
  • C#生成随机数功能示例

    C#生成随机数功能示例

    这篇文章主要介绍了C#生成随机数功能,涉及C#数学运算与字符串操作相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2017-01-01
  • c#学习教程之JSON文件及解析实例

    c#学习教程之JSON文件及解析实例

    json作为互联网上轻量便捷的数据传输格式,越来越受到重视,下面这篇文章主要给大家介绍了关于c#学习教程之JSON文件及解析的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • 基于C#实现员工IC卡的读写功能

    基于C#实现员工IC卡的读写功能

    这篇文章主要为大家详细介绍了C#如何实现读写员工IC卡的功能,文中的示例代码讲解详细,对我们学习C#有一定的帮助,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-01-01
  • C#抓取网络图片保存到本地的实现方法

    C#抓取网络图片保存到本地的实现方法

    下面小编就为大家分享一篇C#抓取网络图片保存到本地的实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • 利用C#守护Python进程的方法

    利用C#守护Python进程的方法

    这篇文章主要给大家介绍了关于如何利用C#守护Python进程的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C#具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-10-10
  • C#多线程之线程控制详解

    C#多线程之线程控制详解

    这篇文章主要为大家详细介绍了C#多线程之线程控制的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08

最新评论