WPF TextBox按位元組長度限制輸入

来源:http://www.cnblogs.com/ZXdeveloper/archive/2017/11/07/7798943.html
-Advertisement-
Play Games

前兩天做一個項目的時候,由於頁面沒有限制TextBox的輸入長度,所以,後臺直接報錯了,超出資料庫最大的長度。 資料庫的長度是按照位元組來計算的,而且不同的編碼格式,漢字占用的位元組長度又不相同,比如,我們用的是UTF8,一個漢字是3個位元組,而預設的Default,一個漢字是2個位元組。 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,疏忽了


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Nginx的靜態處理能力很強,但是動態處理能力不足,因此,在企業中常用動靜分離技術。動靜分離技術其實是採用代理的方式,在server{}段中加入帶正則匹配的location來指定匹配項針對PHP的動靜分離:靜態頁面交給Nginx處理,動態頁面交給PHP FPM模塊或Apache處理。在Nginx的配 ...
  • vim 插入模式 a 游標後 A 行尾 o 游標所在行下一行 O 游標所在行上一行 i 游標前 I 行首 s 刪除游標所在位置的字元併進入插入模式 命令模式 d 刪除 dd 刪除當前行 dgg 刪除游標到文檔首 dG 刪除游標到文檔尾部 d$ 刪除游標到行尾,包括游標所在位置字元 d^ 刪除游標到行 ...
  • 1.使用xshell連接虛擬機,也可直接在虛擬機中敲命令。 以下是xshell上的命令: 首先安裝HTTPD包 [root@one ~]# mount /dev/sr0 /mnt[root@one ~]# yum install httpd重啟服務查看靜態 [root@one ~]# systemc ...
  • 本文將通過場景例子演示,來通俗易懂的講解在複雜的業務邏輯下,如何以最簡練的代碼,最直觀的編寫事務代碼。 通過一系列優化最終達到兩個效果,1.通過代碼塊來控制事務(分散式事務),2.通過委托優化TransactionScope的編碼寫法。 本文需要的知識點:1. Action委托 2. 分散式事務Tr ...
  • 在ABP官網創建一個.Net Core項目編譯完成 1、 發佈網站 2、 IIS新建站點 目錄指向發佈的目錄 3、安裝WindowsHosting IIS安裝伺服器上安裝DotNetCore.X.X.X-WindowsHosting安裝成功後重啟IIS伺服器。根據版本選擇下載 下載地址:https: ...
  • 一、設計目的:讓項目中只顯示一個實例對象 二、設計步驟: 三、項目相關名詞或知識點解釋 此處類類型:如果當前類為SingleCase,則此靜態變數類型也要為SingleCase類型, 即在此處定義的靜態變數的類型要和這個當前類的類型相同 定義單例實例變數時,儘量都用instance(實例)來指代,方 ...
  • 近乎產品的數據訪問是基於輕量級ORM——PetaPoco,哪怕是他們最新的5.2版本也是基於PetaPoco。至於為什麼沒有選用EF這些ORM,感興趣的可以去咨詢他們的產品人員,本文就不詳細說明瞭。 關於近乎源碼下載:www.jinhusns.com ...
  • Asp.Net Web API不可以需要IIS。可以自己在主機上承載一個Web API 創建WebAPI.Server項目 創建一個控制器項目的服務端 在Nuget中添加Microsoft.AspNet.WebApi.SelfHost 創建Model與Controller 首先在服務端添加一個Pro ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...