zoukankan      html  css  js  c++  java
  • 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, 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,疏忽了

  • 相关阅读:
    类的加载过程
    ASCII码表
    uboot main_loop函数分析
    串行CPU设计
    __attribute__ ((section(".text")))的测试
    NandFlash
    测试gcc的优化选项
    如何编写一个简单的makefile
    UBOOT的多支持性与可裁剪性
    函数指针的使用
  • 原文地址:https://www.cnblogs.com/ZXdeveloper/p/7798943.html
Copyright © 2011-2022 走看看