(C#)为 TextBox 控件增加一个限制最大字节数的属性
生活随笔
收集整理的這篇文章主要介紹了
(C#)为 TextBox 控件增加一个限制最大字节数的属性
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一直以來都知道,在 sql server 中,varchar類型是按字節計算的。例如 varchar(50)? 可以存儲50個英文字符,但只能存儲25個中文字符(一個中文字符2個字節)。改為 nvarchar 可以解決這個問題,但在寫sql語句的時候必須加上N標識,否則會產生亂碼。
但最近用 C# 做數據庫項目,才知道問題很嚴重。本來輸入的合法性就應該在界面上做好限制,例如對于varchar(50)?的字段,能在界面上控制用戶不能輸入超過50個單字節字符,是最好不過的了。然后發現 textbox?的 MaxLength 計算的只是 Unicode 長度。
對于 Unicode ,我這里就不做描述了。設置 MaxLength? 是不能很好的保證輸入的合法性。因此我決定為 textbox 增加一個限制最大字節數的屬性:MaxByteLength 。
建立新組件
我們先新建一個組件 TextBoxEx,繼承于 TextBox ,增加一個 MaxByteLength? 屬性
public?partial?class?TextBoxEx?:?TextBox
????{
????????public?TextBoxEx()
????????{
????????????InitializeComponent();
????????}
????????屬性#region?屬性
????????private?int?m_MaxByteLength?=?0;
????????[Description("獲取或設置用戶可在文本框控件中鍵入或粘貼的最大字節數。0?為允許無限長度。")]
????????/**////?<summary>
????????///?獲取或設置用戶可在文本框控件中鍵入或粘貼的最大字節數。0?為允許無限長度。
????????///?</summary>
????????public?int?MaxByteLength
????????{
????????????get?{?return?m_MaxByteLength;?}
????????????set?{?m_MaxByteLength?=?value;?}
????????}
}
然后重寫 WndProc ,實現輸入和粘貼的時候對字節長度進行判斷。(已修正輸入“.”號沒有判斷的問題)
????????protected?override?void?WndProc(ref?Message?m)
????????{
????????????//如果該屬性沒有設置,則允許輸入
????????????if?(m_MaxByteLength?==?0)
????????????{
????????????????base.WndProc(ref?m);
????????????????return;
????????????}
????????????switch?(m.Msg)
????????????{
????????????????case?WM_CHAR:
????????????????????int?i?=?(int)m.WParam;
????????????????????bool?isBack?=?(i?==?(int)Keys.Back);
????????????????????bool?isCtr?=?(i?==?24)?||?(i?==?22)?||?(i?==?26)?||?(i?==?3);
????????????????????if?(isBack?||?isCtr)
????????????????????{
????????????????????????//控制鍵不作處理
????????????????????}
????????????????????else
????????????????????{
????????????????????????char?c?=?(char)i;
????????????????????????if?(CheckByteLengthFlow(c.ToString()))
????????????????????????{
????????????????????????????break;
????????????????????????}
????????????????????}
????????????????????base.WndProc(ref?m);
????????????????????break;
????????????????case?WM_PASTE:
????????????????????IDataObject?iData?=?Clipboard.GetDataObject();//取剪貼板對象
????????????????????if?(iData.GetDataPresent(DataFormats.Text))?//判斷是否是Text
????????????????????{
????????????????????????string?text?=?(string)iData.GetData(DataFormats.Text);//取數據
????????????????????????if?(CheckByteLengthFlow(text))
????????????????????????{
????????????????????????????m.Result?=?(IntPtr)0;//不可以粘貼
????????????????????????????break;
????????????????????????}
????????????????????}
????????????????????base.WndProc(ref?m);
????????????????????break;
????????????????default:
????????????????????base.WndProc(ref?m);
????????????????????break;
????????????}
????????}
????????///?<summary>
????????///?判斷即將輸入的文本長度是否溢出
????????///?</summary>
????????///?<param?name="text">文本</param>
????????///?<returns>是否溢出</returns>
????????private?bool?CheckByteLengthFlow(string?text)
????????{
????????????int?len?=?GetByteLength(text);????//輸入的字符的長度
????????????int?tlen?=?GetByteLength(this.Text);??//文本框原有文本的長度
????????????int?slen?=?GetByteLength(this.SelectedText);????//文本框選中文本的長度
????????????return?(m_MaxByteLength?<?(tlen?-?slen?+?len));
????????}
????????///?<summary>
????????///?計算文本字節長度,區分多字節字符
????????///?</summary>
????????///?<param?name="text">文本</param>
????????///?<returns>文本字節長度</returns>
????????private?int?GetByteLength(string?text)
????????{
????????????return?System.Text.Encoding.Default.GetBytes(text).Length;
????????}
另外,增加一個 RealText 屬性,該屬性返回具有合法長度的文本, 不會截斷多字節字符
public?string?RealText
????????{
????????????get
????????????{
????????????????if?(m_MaxByteLength?==?0)
????????????????{
????????????????????return?this.Text;
????????????????}
????????????????if?(m_MaxByteLength?>=?GetByteLength(this.Text))
????????????????{
????????????????????return?this.Text;
????????????????}
????????????????string?text?=?this.Text;
????????????????if?(string.IsNullOrEmpty(text))
????????????????{
????????????????????return?text;
????????????????}
????????????????char[]?c?=?text.ToCharArray();
????????????????StringBuilder?sb?=?new?StringBuilder();
????????????????int?count?=?0;
????????????????for?(int?i?=?0;?i?<?c.Length;?i++)
????????????????{
????????????????????count?+=?GetByteLength(c[i].ToString());
????????????????????if?(m_MaxByteLength?>=?count)
????????????????????{
????????????????????????sb.Append(c[i]);
????????????????????}
????????????????}
????????????????return?sb.ToString();
????????????}
????????}
至此,可以通過設置 MaxByteLength? 來限制最大字節數了。
源代碼下載:/Files/lemony/TextBoxExTest_OLD.rar 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
但最近用 C# 做數據庫項目,才知道問題很嚴重。本來輸入的合法性就應該在界面上做好限制,例如對于varchar(50)?的字段,能在界面上控制用戶不能輸入超過50個單字節字符,是最好不過的了。然后發現 textbox?的 MaxLength 計算的只是 Unicode 長度。
對于 Unicode ,我這里就不做描述了。設置 MaxLength? 是不能很好的保證輸入的合法性。因此我決定為 textbox 增加一個限制最大字節數的屬性:MaxByteLength 。
建立新組件
我們先新建一個組件 TextBoxEx,繼承于 TextBox ,增加一個 MaxByteLength? 屬性
public?partial?class?TextBoxEx?:?TextBox
????{
????????public?TextBoxEx()
????????{
????????????InitializeComponent();
????????}
????????屬性#region?屬性
????????private?int?m_MaxByteLength?=?0;
????????[Description("獲取或設置用戶可在文本框控件中鍵入或粘貼的最大字節數。0?為允許無限長度。")]
????????/**////?<summary>
????????///?獲取或設置用戶可在文本框控件中鍵入或粘貼的最大字節數。0?為允許無限長度。
????????///?</summary>
????????public?int?MaxByteLength
????????{
????????????get?{?return?m_MaxByteLength;?}
????????????set?{?m_MaxByteLength?=?value;?}
????????}
}
然后重寫 WndProc ,實現輸入和粘貼的時候對字節長度進行判斷。(已修正輸入“.”號沒有判斷的問題)
????????protected?override?void?WndProc(ref?Message?m)
????????{
????????????//如果該屬性沒有設置,則允許輸入
????????????if?(m_MaxByteLength?==?0)
????????????{
????????????????base.WndProc(ref?m);
????????????????return;
????????????}
????????????switch?(m.Msg)
????????????{
????????????????case?WM_CHAR:
????????????????????int?i?=?(int)m.WParam;
????????????????????bool?isBack?=?(i?==?(int)Keys.Back);
????????????????????bool?isCtr?=?(i?==?24)?||?(i?==?22)?||?(i?==?26)?||?(i?==?3);
????????????????????if?(isBack?||?isCtr)
????????????????????{
????????????????????????//控制鍵不作處理
????????????????????}
????????????????????else
????????????????????{
????????????????????????char?c?=?(char)i;
????????????????????????if?(CheckByteLengthFlow(c.ToString()))
????????????????????????{
????????????????????????????break;
????????????????????????}
????????????????????}
????????????????????base.WndProc(ref?m);
????????????????????break;
????????????????case?WM_PASTE:
????????????????????IDataObject?iData?=?Clipboard.GetDataObject();//取剪貼板對象
????????????????????if?(iData.GetDataPresent(DataFormats.Text))?//判斷是否是Text
????????????????????{
????????????????????????string?text?=?(string)iData.GetData(DataFormats.Text);//取數據
????????????????????????if?(CheckByteLengthFlow(text))
????????????????????????{
????????????????????????????m.Result?=?(IntPtr)0;//不可以粘貼
????????????????????????????break;
????????????????????????}
????????????????????}
????????????????????base.WndProc(ref?m);
????????????????????break;
????????????????default:
????????????????????base.WndProc(ref?m);
????????????????????break;
????????????}
????????}
????????///?<summary>
????????///?判斷即將輸入的文本長度是否溢出
????????///?</summary>
????????///?<param?name="text">文本</param>
????????///?<returns>是否溢出</returns>
????????private?bool?CheckByteLengthFlow(string?text)
????????{
????????????int?len?=?GetByteLength(text);????//輸入的字符的長度
????????????int?tlen?=?GetByteLength(this.Text);??//文本框原有文本的長度
????????????int?slen?=?GetByteLength(this.SelectedText);????//文本框選中文本的長度
????????????return?(m_MaxByteLength?<?(tlen?-?slen?+?len));
????????}
????????///?<summary>
????????///?計算文本字節長度,區分多字節字符
????????///?</summary>
????????///?<param?name="text">文本</param>
????????///?<returns>文本字節長度</returns>
????????private?int?GetByteLength(string?text)
????????{
????????????return?System.Text.Encoding.Default.GetBytes(text).Length;
????????}
另外,增加一個 RealText 屬性,該屬性返回具有合法長度的文本, 不會截斷多字節字符
public?string?RealText
????????{
????????????get
????????????{
????????????????if?(m_MaxByteLength?==?0)
????????????????{
????????????????????return?this.Text;
????????????????}
????????????????if?(m_MaxByteLength?>=?GetByteLength(this.Text))
????????????????{
????????????????????return?this.Text;
????????????????}
????????????????string?text?=?this.Text;
????????????????if?(string.IsNullOrEmpty(text))
????????????????{
????????????????????return?text;
????????????????}
????????????????char[]?c?=?text.ToCharArray();
????????????????StringBuilder?sb?=?new?StringBuilder();
????????????????int?count?=?0;
????????????????for?(int?i?=?0;?i?<?c.Length;?i++)
????????????????{
????????????????????count?+=?GetByteLength(c[i].ToString());
????????????????????if?(m_MaxByteLength?>=?count)
????????????????????{
????????????????????????sb.Append(c[i]);
????????????????????}
????????????????}
????????????????return?sb.ToString();
????????????}
????????}
至此,可以通過設置 MaxByteLength? 來限制最大字節數了。
源代碼下載:/Files/lemony/TextBoxExTest_OLD.rar 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的(C#)为 TextBox 控件增加一个限制最大字节数的属性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IBM服务器巡检流程
- 下一篇: ASP.NET和C#中对XML的操作,以