1. 前言
最近在寫定GPS定位時,經緯度是用的double類型,并且經緯度的要求是小數點后最少6位,多了能達到17位,又遇到了常用的TextBox控件只能輸入數字、小數的功能,因為有一年多沒有寫程序,現在再來寫這些感覺已經忘記的差不多了,這次干脆把功能進行擴展,寫到這里以作記錄,并分享與大家。
2. 功能
(1)TextBox文本框只能輸入0-9和小數點以及BackSpace刪除鍵。
(2)文本框小數點只能有一位。
(3)文本框內第一位如果直接輸入小數點,會自動在其前面補0,形成“0.”開頭的格式。
(4)因為TexbBox控件增加了我們自己“只能輸入數字小數點和刪除鍵功能”的KeyPress事件,會導致TextBox控件的Ctrl+C和Ctrl+V功能失效,只能用鼠標來執行復制粘貼,所以此次通過TextBox控件的KeyDown事件進行了修復,文本框的復制和粘貼功能又恢復正常。
(5)對文本框Ctrl+V粘貼剪切板的內容進行了處理,把剪切板內非數字和小數點部分過濾掉了。也就是說你復制了含有字母、漢字、空格、特殊符號等非數字字符,粘貼到文本框時會把它們去掉,只留下含有數字的部分。
(6)其余對文本框選中內容的操作,我們處理的跟Windows系統操作方法一樣。
3. 程序代碼
/// <summary>/// 只能輸入數字、小數點、刪除鍵,并且第1位輸入小數點,自動在前面補0,形成"0."格式/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void NumPointKeypress(object sender, KeyPressEventArgs e){//除了數字、小數點、刪除鍵的其他鍵,程序不輸出if (!((e.KeyChar >= '0' && e.KeyChar <= '9') || e.KeyChar == '.' || e.KeyChar == (char)Keys.Back)){e.Handled = true;}//按鍵是小數點if (e.KeyChar == '.'){//獲取當前文本框對象TextBox textbox = sender as TextBox;//文本框的文本已經有小數點if (textbox.Text.IndexOf('.') >= 0){//文本框選定的文本包括小數點,再次輸入小數點時就把選定的內容刪除并換成小數點if (textbox.SelectedText.Contains(".")){//選定帶小數點文本的起始位置(索引)int Index = textbox.SelectionStart;//從第一位開始選定帶小數點的文本,輸入小數點時直接在前面補0,形成"0."開頭的文本,光標置于小數點后if (Index == 0){textbox.Text = textbox.Text.Remove(Index, textbox.SelectionLength).Insert(Index, "0.");textbox.SelectionStart = Index + 2;}else//選定小數點的文本是起始位置在第一位之后,再次輸入小數點直接將選定內容替換成小數點,光標置于小數點后{textbox.Text = textbox.Text.Remove(Index, textbox.SelectionLength).Insert(Index, ".");textbox.SelectionStart = Index + 1;}textbox.SelectionLength = 0;// 確保沒有文本被選中}e.Handled = true;}else if (string.IsNullOrEmpty(textbox.Text))//文本框不含小數點,并且文本框內容為空{//方法1:直接將小數點寫入文本起始位置,格式"0.",按鍵不輸出//textbox.Text = "0.";//textbox.SelectionStart = 2; //光標在文本框中第三個字符處(位置索引為2)//textbox.SelectionLength = 0; // 確保沒有文本被選中//e.Handled = true;//方法2:不寫入小數點,在文本起始位置寫入0,按鍵輸出小數點textbox.Text = "0";textbox.SelectionStart = 1; //光標在文本框中第二個字符處(位置索引為2)textbox.SelectionLength = 0; // 確保沒有文本被選中}else if (!string.IsNullOrEmpty(textbox.Text))//文本框不含小數點,并且文本框已經有內容{/* * 光標位于文本框最前面,用一條語句解決下面兩種情況:* 第一種情況,有選定內容,直接刪除后插入"0",按鍵再輸出小數點,* 第二種情況,沒有選定內容,下面語句text.Text.Remove(0,0)相當于沒有替換,* 也是直接在文本最前面插入了"0",按鍵再輸出小數點,*/if (textbox.SelectionStart == 0){textbox.Text = textbox.Text.Remove(0, textbox.SelectionLength).Insert(0, "0");textbox.SelectionStart = 1; //光標置于小數點后textbox.SelectionLength = 0; // 確保沒有文本被選中}//光標不在文本框最前面,在其他任意位置,文本內容選中與不選中,都會按系統自己的方式插入小數點。}}}/// <summary>/// 允許文本框復制、粘貼/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void NumPointKeydown(object sender, KeyEventArgs e){TextBox textbox = sender as TextBox;if (e.KeyData == (Keys.Control | Keys.C)){Clipboard.SetDataObject(textbox.SelectedText);}if (e.KeyData == (Keys.Control | Keys.V)){//文本框中的文本未選中情況下,把剪切板中的插入光標處if (textbox.SelectionLength == 0){//將原文本框中的文本與插入剪切板中的字符進行過濾(如果剪切板中有非數字字符,多余一位的小數點都將去除)textbox.Text = FilterString(textbox.Text.Insert(textbox.SelectionStart, Clipboard.GetText()));}else//文本在選中情況下,刪除掉選中的文本,再把剪切板中的插入此處{int Index = textbox.SelectionStart;textbox.Text = textbox.Text.Remove(Index, textbox.SelectionLength).Insert(Index, Clipboard.GetText());//將原文本框中的文本與插入剪切板中的字符進行過濾(如果剪切板中有非數字字符,多余一位的小數點都將去除)textbox.Text = FilterString(textbox.Text);}//粘貼完成后,光標置于文本最后textbox.SelectionStart = textbox.Text.Length;}}/// <summary>/// 把剪切板中的英文、漢字、特殊字符等非數字字符過濾掉/// 如果存在多個小數點,只留第一位小數點/// </summary>/// <param name="clipboardText">剪切板組合的內容</param>/// <returns>返回整數或浮點數字符串</returns>private string FilterString(string clipboardText){// 匹配浮點數或整數string pattern = @"[+-]?(\d+(\.\d*)?|\.\d+)";System.Text.RegularExpressions.MatchCollection matches = System.Text.RegularExpressions.Regex.Matches(clipboardText, pattern);string Filterstring = string.Empty;foreach (System.Text.RegularExpressions.Match match in matches){Filterstring += match.Value;}//如果存在多個小數點,留下第一個小數點,其他的都刪除int PointCounts = Filterstring.Where(p => p == '.').Count();if (PointCounts >= 2){for (int i = 0; i < PointCounts - 1; i++){Filterstring = Filterstring.Remove(Filterstring.LastIndexOf('.'), 1);}}//過濾后不存在數字部分則返回字符0if (string.IsNullOrEmpty(Filterstring))return "0";else{//過濾后第一位是小數點,則在其前面加0if (Filterstring.FirstOrDefault() == '.')Filterstring = "0" + Filterstring;return Filterstring;}}
注意:如果在Ctrl+V粘貼時不需要對剪切板中的內容進行過濾,而是直接要使用剪切板的內容,可以在NumPointKeydown()事件中使用 textbox.Text = Clipboard.GetText(),就不需要再調用FilterString()字符過濾函數了。
4. 調用
可以在窗口文件的構造函數中直接調用,也可以在窗口載入事件Load()中調用,以窗口構造函數為例。
public Form1(){InitializeComponent();//綁定事件以下事件://1、文本框只能輸入數字、小數點、刪除鍵的事件textBox1.KeyPress += NumPointKeypress;textBox2.KeyPress += NumPointKeypress;//2、文本框允許復制、粘貼textBox1.KeyDown += NumPointKeydown;textBox2.KeyDown += NumPointKeydown;}