(C#)为 TextBox 控件增加一个限制最大字节数的属性
生活随笔
收集整理的這篇文章主要介紹了
(C#)为 TextBox 控件增加一个限制最大字节数的属性
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一直以來都知道,在 sql server 中,varchar類型是按字節(jié)計(jì)算的。例如 varchar(50)? 可以存儲50個(gè)英文字符,但只能存儲25個(gè)中文字符(一個(gè)中文字符2個(gè)字節(jié))。改為 nvarchar 可以解決這個(gè)問題,但在寫sql語句的時(shí)候必須加上N標(biāo)識,否則會產(chǎn)生亂碼。
但最近用 C# 做數(shù)據(jù)庫項(xiàng)目,才知道問題很嚴(yán)重。本來輸入的合法性就應(yīng)該在界面上做好限制,例如對于varchar(50)?的字段,能在界面上控制用戶不能輸入超過50個(gè)單字節(jié)字符,是最好不過的了。然后發(fā)現(xiàn) textbox?的 MaxLength 計(jì)算的只是 Unicode 長度。
對于 Unicode ,我這里就不做描述了。設(shè)置 MaxLength? 是不能很好的保證輸入的合法性。因此我決定為 textbox 增加一個(gè)限制最大字節(jié)數(shù)的屬性:MaxByteLength 。
建立新組件
我們先新建一個(gè)組件 TextBoxEx,繼承于 TextBox ,增加一個(gè) MaxByteLength? 屬性
public?partial?class?TextBoxEx?:?TextBox
????{
????????public?TextBoxEx()
????????{
????????????InitializeComponent();
????????}
????????屬性#region?屬性
????????private?int?m_MaxByteLength?=?0;
????????[Description("獲取或設(shè)置用戶可在文本框控件中鍵入或粘貼的最大字節(jié)數(shù)。0?為允許無限長度。")]
????????/**////?<summary>
????????///?獲取或設(shè)置用戶可在文本框控件中鍵入或粘貼的最大字節(jié)數(shù)。0?為允許無限長度。
????????///?</summary>
????????public?int?MaxByteLength
????????{
????????????get?{?return?m_MaxByteLength;?}
????????????set?{?m_MaxByteLength?=?value;?}
????????}
}
然后重寫 WndProc ,實(shí)現(xiàn)輸入和粘貼的時(shí)候?qū)ψ止?jié)長度進(jìn)行判斷。(已修正輸入“.”號沒有判斷的問題)
????????protected?override?void?WndProc(ref?Message?m)
????????{
????????????//如果該屬性沒有設(shè)置,則允許輸入
????????????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);//取數(shù)據(jù)
????????????????????????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>
????????///?計(jì)算文本字節(jié)長度,區(qū)分多字節(jié)字符
????????///?</summary>
????????///?<param?name="text">文本</param>
????????///?<returns>文本字節(jié)長度</returns>
????????private?int?GetByteLength(string?text)
????????{
????????????return?System.Text.Encoding.Default.GetBytes(text).Length;
????????}
另外,增加一個(gè) RealText 屬性,該屬性返回具有合法長度的文本, 不會截?cái)喽嘧止?jié)字符
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();
????????????}
????????}
至此,可以通過設(shè)置 MaxByteLength? 來限制最大字節(jié)數(shù)了。
源代碼下載:/Files/lemony/TextBoxExTest_OLD.rar 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎
但最近用 C# 做數(shù)據(jù)庫項(xiàng)目,才知道問題很嚴(yán)重。本來輸入的合法性就應(yīng)該在界面上做好限制,例如對于varchar(50)?的字段,能在界面上控制用戶不能輸入超過50個(gè)單字節(jié)字符,是最好不過的了。然后發(fā)現(xiàn) textbox?的 MaxLength 計(jì)算的只是 Unicode 長度。
對于 Unicode ,我這里就不做描述了。設(shè)置 MaxLength? 是不能很好的保證輸入的合法性。因此我決定為 textbox 增加一個(gè)限制最大字節(jié)數(shù)的屬性:MaxByteLength 。
建立新組件
我們先新建一個(gè)組件 TextBoxEx,繼承于 TextBox ,增加一個(gè) MaxByteLength? 屬性
public?partial?class?TextBoxEx?:?TextBox
????{
????????public?TextBoxEx()
????????{
????????????InitializeComponent();
????????}
????????屬性#region?屬性
????????private?int?m_MaxByteLength?=?0;
????????[Description("獲取或設(shè)置用戶可在文本框控件中鍵入或粘貼的最大字節(jié)數(shù)。0?為允許無限長度。")]
????????/**////?<summary>
????????///?獲取或設(shè)置用戶可在文本框控件中鍵入或粘貼的最大字節(jié)數(shù)。0?為允許無限長度。
????????///?</summary>
????????public?int?MaxByteLength
????????{
????????????get?{?return?m_MaxByteLength;?}
????????????set?{?m_MaxByteLength?=?value;?}
????????}
}
然后重寫 WndProc ,實(shí)現(xiàn)輸入和粘貼的時(shí)候?qū)ψ止?jié)長度進(jìn)行判斷。(已修正輸入“.”號沒有判斷的問題)
????????protected?override?void?WndProc(ref?Message?m)
????????{
????????????//如果該屬性沒有設(shè)置,則允許輸入
????????????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);//取數(shù)據(jù)
????????????????????????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>
????????///?計(jì)算文本字節(jié)長度,區(qū)分多字節(jié)字符
????????///?</summary>
????????///?<param?name="text">文本</param>
????????///?<returns>文本字節(jié)長度</returns>
????????private?int?GetByteLength(string?text)
????????{
????????????return?System.Text.Encoding.Default.GetBytes(text).Length;
????????}
另外,增加一個(gè) RealText 屬性,該屬性返回具有合法長度的文本, 不會截?cái)喽嘧止?jié)字符
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();
????????????}
????????}
至此,可以通過設(shè)置 MaxByteLength? 來限制最大字節(jié)數(shù)了。
源代碼下載:/Files/lemony/TextBoxExTest_OLD.rar 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎
總結(jié)
以上是生活随笔為你收集整理的(C#)为 TextBox 控件增加一个限制最大字节数的属性的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IBM服务器巡检流程
- 下一篇: 国内CRM市场的运作猜想