2013-03-06 51 views
2

我想創建某種類型的許可證驗證文本框,自動將用戶輸入拆分爲由連字符分隔的塊。我的執照是25個字符長,而且分開,例如:解析用戶輸入作爲用戶鍵入WinForms文本框控件

XXXXX-XXXXX-XXXXX-XXXXX-XXXXX

我想出了下面的代碼來分析用戶的輸入,而他是打字或通過複製/粘貼通過處理TextChanged事件TextBox控件像這樣的:

public static string InsertStringAtInterval(string source, string insert, int interval) 
     { 
      StringBuilder result = new StringBuilder(); 
      int currentPosition = 0; 
      while (currentPosition + interval < source.Length) 
      { 
       result.Append(source.Substring(currentPosition, interval)).Append(insert); 
       currentPosition += interval; 
      } 
      if (currentPosition < source.Length) 
      { 
       result.Append(source.Substring(currentPosition)); 
      } 
      return result.ToString(); 
     } 

     private bool bHandlingChangeEvent = false; 
     private void txtLicense_TextChanged(object sender, EventArgs e) 
     { 
      if (bHandlingChangeEvent == true) 
       return; 

      bHandlingChangeEvent = true; 
      string text = txtLicense.Text.Replace("-", "").Replace(" ",""); 
      int nPos = txtLicense.SelectionStart; 
      if((text.Length==5||text.Length==10||text.Length==15||text.Length==20) && txtLicense.Text[txtLicense.Text.Length-1]!='-') 
      { 
       txtLicense.Text += "-"; 
       txtLicense.SelectionStart = nPos + 1; 
      } 
      if(text.Length>=25) 
      { 
       string tmp = text.Substring(0, 25); 
       tmp = InsertStringAtInterval(tmp, "-", 5); 
       txtLicense.Text = tmp; 
       txtLicense.SelectionStart = nPos; 
      } 


      bHandlingChangeEvent = false; 
     } 

雖然這是正常使用時,我的用戶類型和箱內膏。我唯一的問題是,當用戶試圖通過按退格鍵或刪除鍵從輸入的鍵中刪除字符時。

由於強制連字符插入@位置5,10,15,20,一旦用戶在退格按下這些標記之一時,按上述邏輯強制連字符添加到字符串,並且用戶不能超出該範圍。

我試着擺弄KeyDown事件,但不能拿出任何有用的東西。有人可以幫忙嗎?

我也嘗試過使用MaskedTextbox,但那件事很醜陋,因爲我不想讓遮罩/連字符在焦點上可見,我當然不想用空格替換提示,因爲它會給一些混淆當在盒子內部點擊時,由於當其「假定」爲空時,光標不會始終位於盒子的開始處。

+1

會[MaskedTextBox](http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.aspx)有幫助嗎? – publicgk 2013-03-06 15:23:39

+0

我剛剛編輯了我關於那個問題,因爲我以爲有人會提到它..檢查我的問題的結束 – 2013-03-06 15:24:13

+0

@DJKRAZE不知道你在瞄準什麼..你能在代碼中解釋也許 – 2013-03-06 17:32:43

回答

2

這樣的事情已經有很多多年來爲我痛苦的原因。我接近它的方式是將文本中的每個更改都視爲從頭開始粘貼 - 我將連字符去掉,然後將它們放回到適當的位置。然後,您可以處理用戶刪除最後一個字符的特殊情況。在這種情況下,您將TextChanged事件之前的文本與之後的文本進行比較。如果它們是相同的,但前面的文字只是一個字符,就不要做任何特別的事情。

下面是一些代碼,似乎適用於文本輸入,剪切/複製/粘貼等。它可以改進一點花哨的LINQ,一些錯誤處理等,但希望它能得到這個想法。

private string previousText = string.Empty; 
private bool processing = false; 

private void textBox1_TextChanged(object sender, EventArgs e) 
{ 
    // If we're already messing around with the text, don't start again. 
    if (processing) 
     return; 

    processing = true; 

    // The current textbox text 
    string newText = textBox1.Text; 

    // What was there before, minus one character. 
    string previousLessOne = previousText == string.Empty ? string.Empty : previousText.Substring(0, previousText.Length - 1); 

    // Get where the user is, minus any preceding dashes 
    int caret = textBox1.SelectionStart - (textBox1.Text.Substring(0, textBox1.SelectionStart).Count(ch => ch == '-')); 

    // If the user has done anything other than delete the last character, ensure dashes are placed in the correct position. 
    if (newText.Length > 0 && newText != previousLessOne) 
    { 
     textBox1.Text = string.Empty; 
     newText = newText.Replace("-", ""); 

     for (int i = 0; i < newText.Length; i += 5) 
     { 
      int length = Math.Min(newText.Length - i, 5); 
      textBox1.Text += newText.Substring(i, length); 

      if (length == 5) 
       textBox1.Text += '-'; 
     } 
    } 

    // Put the user back where they were, adjusting for dashes. 
    textBox1.SelectionStart = caret + (caret/5); 

    previousText = textBox1.Text; 

    processing = false; 
} 
2

你可以試試這個版本:類似這樣的前

void txtLicense_KeyDown(object sender, KeyEventArgs e) { 
    if (e.KeyCode == Keys.Back) { 

    int index = txtLicense.SelectionStart; 
    while (index > 0 && txtLicense.Text[index - 1] == '-') { 
     --index; 
    } 

    if (index > 0) { 
     --index; 
    } 

    txtLicense.Select(index, txtLicense.SelectionLength + Math.Max(index, 1)); 
    txtLicense.SelectedText = string.Empty; 

    e.SuppressKeyPress = true; 
    } 
} 
1

我已經做了一些。我要做的就是在插入點後面有一個字符之前不要添加連字符。例如,不要在輸入5個字符後添加連字符,而應在6處添加連字符,以避免在末尾添加連字符。

下面是我用在特定的位置插入連字符的算法:

public static string FormatLicenseNumber(string str) 
{ 
    if (string.IsNullOrEmpty(str)) 
     return str; 
    else 
    { 
     str = str.Replace("-", string.Empty); 
     if (str.Length > 20) 
      str = str.Insert(20, "-"); 
     if (str.Length > 15) 
      str = str.Insert(15, "-"); 
     if (str.Length > 10) 
      str = str.Insert(10, "-"); 
     if (str.Length > 5) 
      str = str.Insert(5, "-"); 
     return str; 
    } 
}