2013-06-04 105 views
0

我有幾個textboxes,我希望光標使用箭頭鍵從一個textbox移動到另一個。如何使用箭頭在文本框之間移動光標?

我該怎麼做?

它看起來像這樣,水龍頭也垂直移動,這很奇怪。

謝謝。 enter image description here

+0

使用KeyPress。您可能還需要使用SelectionStart檢查光標位置 – David

回答

2

可以重寫窗體的ProcessCmdKey功能,並辦理按鍵,專注於文本框在裏面。

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace TextBoxes 
{ 
    public partial class Form1 : Form 
    { 

     List<TextBox[]> _textBoxes; 
     public Form1() 
     { 
      InitializeComponent(); 

      //Getting a 2 dimentional structure to hold textboxes 
      this._textBoxes= new List<TextBox[]>(); 

      TextBox[] row1 = new TextBox[4]; 
      row1[0] = textBox1; 
      row1[1] = textBox2; 
      row1[2] = textBox3; 
      row1[3] = textBox4; 

      TextBox[] row2 = new TextBox[4]; 
      row2[0] = textBox5; 
      row2[1] = textBox6; 
      row2[2] = textBox7; 
      row2[3] = textBox8; 

      TextBox[] row3 = new TextBox[4]; 
      row3[0] = textBox9; 
      row3[1] = textBox10; 
      row3[2] = textBox11; 
      row3[3] = textBox12; 

      TextBox[] row4 = new TextBox[4]; 
      row4[0] = textBox13; 
      row4[1] = textBox14; 
      row4[2] = textBox15; 
      row4[3] = textBox16; 

      this._textBoxes.Add(row1); 
      this._textBoxes.Add(row2); 
      this._textBoxes.Add(row3); 
      this._textBoxes.Add(row4); 



     } 

     /// <summary> 
     /// Processes a command key. 
     /// </summary> 
     /// <param name="msg">A <see cref="T:System.Windows.Forms.Message"/>, passed by reference, that represents the Win32 message to process.</param> 
     /// <param name="keyData">One of the <see cref="T:System.Windows.Forms.Keys"/> values that represents the key to process.</param> 
     /// <returns> 
     /// true if the keystroke was processed and consumed by the control; otherwise, false to allow further processing. 
     /// </returns> 
     protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 
     { 
      //A key was pressed! 
      Control activeCtrl = this.ActiveControl; 
      TextBox txb = activeCtrl as TextBox; 
      //Handle it only if it was sent when a textbox was focused 
      if (txb != null) 
      { 
       int row; 
       int column; 
       //find out which text box is currently active 
       this.GetTextBoxIndexes(txb, out row, out column); 

       //change indexes according to key stroke 
       if (keyData == Keys.Up) 
       { 
        row--; 
       } 
       else if (keyData == Keys.Down) 
       { 
        row++; 
       } 
       else if (keyData == Keys.Left) 
       { 
        column--; 
       } 
       else if (keyData == Keys.Right) 
       { 
        column++; 
       } 
       //Make sure we are not in negative/out of ranfe index 
       row = Math.Abs(row + 4) % 4; 
       column = Math.Abs(column + 4) % 4; 

       //focus requested text box 
       TextBox slected = this._textBoxes[row][column]; 
       slected.Focus(); 

      } 
      //don't forget not to break the chain... 
      return base.ProcessCmdKey(ref msg, keyData); 


     } 

     /// <summary> 
     /// Gets the text box indexes. 
     /// </summary> 
     /// <param name="txb">The texbox.</param> 
     /// <param name="row">The out row index.</param> 
     /// <param name="column">The out column index.</param> 
     private void GetTextBoxIndexes(TextBox txb, out int row, out int column) 
     { 
      row = -1; 
      column = -1; 
      for (int rowIdx = 0; rowIdx < this._textBoxes.Count; rowIdx++) 
      { 
       TextBox[] currRow = this._textBoxes[rowIdx]; 
       for (int colIdx = 0; colIdx < currRow.Length; colIdx++) 
       { 
        TextBox currTextBox = this._textBoxes[rowIdx][colIdx]; 
        if (currTextBox.Equals(txb)) 
        { 
         row = rowIdx; 
         column = colIdx; 
         return; 
        } 
       } 
      } 
     } 
    } 
} 
+0

我編寫了4x4矩陣文本框的代碼。它可以很容易地被修改爲5x4 ... –

+0

我改變了5x4,但仍然'索引',我改變了這個:'row = Math.Abs​​(row + 5)%5; column = Math.Abs​​(column + 4)%4;' – Liban

+0

@Liban,它爲我工作。你是否將第5行添加到列表中? –

3

如果在文本框中有一些文本,下面的解決方案工作。

首先創建一個KeyDown事件處理程序:

private void textBoxLeft_KeyDown(object sender, KeyEventArgs e) 
    { 
    if (e.KeyCode.Equals(Keys.Right)) 
    { 
     e.Handled = true; 
     //SendKeys.Send("{TAB}"); 
     textBoxRight.Focus(); 
    } 
    } 
    private void textBoxRight_KeyDown(object sender, KeyEventArgs e) 
    { 
    if (e.KeyCode.Equals(Keys.Left)) 
    { 
     e.Handled = true; 
    //SendKeys.Send("+{TAB}"); 
    textBoxLeft.Focus(); 
    } 
} 
0

嘗試處理按鍵事件
→,←可以強制標籤,Shift + Tab鍵分別按下。
只是一個粗略的想法,因爲我從來沒有試過這個。

2

剛剛創造性地將這件事擺在了我頭上。這會給你想要的東西。

第1步創建一個TableLayoutPanel並創建列4和行5.刪除所有原始文本框和 第2步將其添加到您的代碼中。

TextBox[] text = new TextBox[20]; //these are your new textboxes 
    private void Form1_Load(object sender, EventArgs e) 
    { 
     for(int i=0; i<text.Length;i++) text[i] = new TextBox() {Text="0"}; //initialize each textbox 
     tableLayoutPanel1.Controls.AddRange(text); //add textboxes to the tablelayoutpanel 
     for(int i = 0; i<tableLayoutPanel1.Controls.Count;i++) //add everything in the tablelayoutpanel to the same keydown event 
     tableLayoutPanel1.Controls[i].KeyDown+=new KeyEventHandler(tableLayoutPanel1_KeyDown); 
    } 

    void tableLayoutPanel1_KeyDown(object sender, KeyEventArgs e) 
    { // this moves the box focus up down left or right 
     if (e.KeyData == Keys.Left) 
      for (int i = 0; i < text.Length; i++) 
      { 
       if (sender.Equals(text[i])) 
       { text[i - 1 < 0 ? text.Length - 1 : i - 1].Focus(); break; } 
      } 
     else if (e.KeyData == Keys.Right) 
      for (int i = 0; i < text.Length; i++) 
      { 
       if (sender.Equals(text[i])) 
       { text[i + 1 > text.Length - 1 ? 0 : i + 1].Focus(); break; } 
      } 
     else if (e.KeyData == Keys.Up) 
      for (int i = 0; i < text.Length; i++) 
      { 
       if (sender.Equals(text[i])) 
       { text[i - 4 < 0 ? i - 4 + text.Length : i - 4].Focus(); break; } 
      } 
     else if (e.KeyData == Keys.Down) 
      for (int i = 0; i < text.Length; i++) 
      { 
       if (sender.Equals(text[i])) 
       { text[i + 4 > text.Length - 1 ? i + 4 - text.Length : i + 4].Focus(); break; } 
      } 
    } 

這將允許您使用箭頭鍵導航上下左右,它會修復與標籤的問題,所以選項卡現在會去正確的Shift + Tab鍵會回去。此外,此解決方案非常好,因爲如果您上下移動,它會像您直覺上預期的那樣迴轉。另外如果你感覺很好,你現在可以對角地移動。

+0

似乎很好的解決方案,但我不想刪除我原來的文本框,改變將是巨大的..無論如何謝謝。 – Liban

+0

該解決方案從零開始工作良好,但如果您希望實際上可以將現有文本框分配給數組,請確保按順序執行此操作,並且如果將它們全部添加到創建的相同KeyDown事件中,則無需使用TableLayout即可運行。邏輯從作爲按時間順序排列的文本框中工作。在任何情況下,您都可以在下次需要從頭開始製作表格並且不想手動對齊您的包裝箱並節省幾秒鐘時使用它。 – CodeCamper

相關問題