2013-08-03 75 views
4

我有一個項目,我需要關注前一個字段,如果當前是空的,但用戶不斷刪除。就像在某處輸入CD-Key時一樣。你有幾個塊,每個塊有4-5個符號。如果你刪除第三個文本框,例如你會在第三個文本框變爲emprty後被強制回到第二個文本框。C#WPF焦點前一個文本框,如果當前擦除

if (textBox2.Text.Length == 0) 
{ 
    Keyboard.Focus(textBox1); 
} 

此代碼工作正常,但考慮到我已經另一個onfocus事件使TextBox2中只要有重點變成空的,由於上述焦點迫使回textBox1的代碼。所以它是循環的。

如果我理解正確,我需要按下刪除按鈕,對不對?但這是我的問題。我不知道如何插入此代碼

private void Window_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.Key == Key.Delete) 
    { 
     if (textBox2.Text.Length == 0) 
     { 
      Keyboard.Focus(textBox1); 
     } 
    } 
} 

這個函數內部:

private void textBox2_TextChanged(object sender, TextChangedEventArgs e) 
{ 
    if (textBox2.Text.Length == 2) 
    { 
      Keyboard.Focus(textBox3); 
    } 
    // HERE I NEED SOMETHING LIKE ELSE IF (e.Key == Key.Delete) {... 
} 

請幫助我。 UPD。我嘗試了一個更多的解決方案,但它不起作用:

private void textBox2_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.Key == Key.Delete) 
    { 
      if (textBox2.Text.Length == 0) 
      { 
       Keyboard.Focus(textBox1); 
      } 
    } 
} 

回答

1

這裏是任意數量的文本框的通用soution。

的TextBox'es列表的初始化:

private readonly List<TextBox> _textBoxes; 

public MainWindow() 
{ 
    InitializeComponent(); 

    _textBoxes = new List<TextBox> { _textBox1, _textBox2, _textBox3 }; 
} 

與KeyUp事件版本:

private void TextBox_KeyUp(object sender, KeyEventArgs e) 
{ 
    if (e.Key == Key.Tab) 
     return; 

    var current = (TextBox)sender; 
    if (current.Text.Any()) 
     return; 

    var index = _textBoxes.IndexOf(current); 
    if (index == 0) 
     return; 

    var previous = _textBoxes[index - 1]; 
    previous.Focus(); 
    previous.CaretIndex = previous.Text.Length; 
} 

上述版本dissalows通過TextBox'es跳按住場景。爲了解決這個問題,使用TextChanged事件:

private void TextBox_TextChanged(object sender, TextChangedEventArgs e) 
{ 
    var current = (TextBox)sender; 
    if (current.Text.Any()) 
     return; 

    var index = _textBoxes.IndexOf(current); 
    if (index == 0) 
     return; 

    var previous = _textBoxes[index - 1]; 
    previous.Focus(); 
    previous.CaretIndex = previous.Text.Length; 
} 

與PreviewKeyDown第三解決方案只支持Key.Delete:

private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.Key != Key.Delete) 
     return; 

    var current = (TextBox)sender; 
    if (current.Text.Length != 0) 
     return; 

    var index = _textBoxes.IndexOf(current); 
    if (index == 0) 
     return; 

    var previous = _textBoxes[index - 1]; 
    previous.Focus(); 
    previous.CaretIndex = 0; 
} 

第四解決方案還與PreviewKeyDown同時支持Key.Delete和Key.Back:

private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.Key != Key.Delete && e.Key != Key.Back) 
     return; 

    var current = (TextBox)sender; 
    if (current.Text.Length != 0) 
     return; 

    var index = _textBoxes.IndexOf(current); 
    if (index == 0) 
     return; 

    var previous = _textBoxes[index - 1]; 
    previous.Focus(); 

    if (e.Key == Key.Delete) 
     previous.CaretIndex = 0; 
} 
+0

新列表(new [] {_textBox1,_textBox2,_textBox3});我不確定我們需要這裏的下劃線。通常你的解決方案有效,但我不清楚第二部分。爲什麼不能通過KeyDown事件來完成?所以我們根本不需要任何TextChanged修復。你有什麼想法如何使我的答案與KeyDown工作中提供的代碼?請讓我知道。 – Mike

+1

@Mike Key.Delete和Key.Back不會發送到KeyDown事件處理程序,但可以使用PreviewKeyDown。 –

+0

@Mike我相信,維護一個文本框列表是比每個文本框的處理程序更具擴展性,靈活性,可保存性和更少的邏輯重複。 –

0

最後。這一個工程:

private void textBox2_KeyUp(object sender, KeyEventArgs e) 
{ 
    if (e.Key == Key.Delete) 
    { 
      if (textBox2.Text.Length == 0) 
      { 
      Keyboard.Focus(textBox1); 
      } 
    } 
} 
0

這沒有測試,但也應該工作。

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    }   

    private void textBox2_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (textBox2.Text == "") 
     { 
      textBox1.Focus(); 
     } 
    } 

    private void textBox3_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (textBox3.Text == "") 
     { 
      textBox2.Focus(); 
     } 
    }     
}