回答
可以重寫窗體的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;
}
}
}
}
}
}
我編寫了4x4矩陣文本框的代碼。它可以很容易地被修改爲5x4 ... –
我改變了5x4,但仍然'索引',我改變了這個:'row = Math.Abs(row + 5)%5; column = Math.Abs(column + 4)%4;' – Liban
@Liban,它爲我工作。你是否將第5行添加到列表中? –
如果在文本框中有一些文本,下面的解決方案工作。
首先創建一個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();
}
}
嘗試處理按鍵事件
→,←可以強制標籤,Shift + Tab鍵分別按下。
只是一個粗略的想法,因爲我從來沒有試過這個。
剛剛創造性地將這件事擺在了我頭上。這會給你想要的東西。
第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鍵會回去。此外,此解決方案非常好,因爲如果您上下移動,它會像您直覺上預期的那樣迴轉。另外如果你感覺很好,你現在可以對角地移動。
似乎很好的解決方案,但我不想刪除我原來的文本框,改變將是巨大的..無論如何謝謝。 – Liban
該解決方案從零開始工作良好,但如果您希望實際上可以將現有文本框分配給數組,請確保按順序執行此操作,並且如果將它們全部添加到創建的相同KeyDown事件中,則無需使用TableLayout即可運行。邏輯從作爲按時間順序排列的文本框中工作。在任何情況下,您都可以在下次需要從頭開始製作表格並且不想手動對齊您的包裝箱並節省幾秒鐘時使用它。 – CodeCamper
- 1. VB.net通過鍵盤在文本框之間移動箭頭
- 2. 如何使用箭頭鍵移動鼠標光標
- 3. PyQT5使用箭頭鍵在列表框之間移動焦點
- 4. 箭頭鍵移動文本框
- 5. 使用箭頭光標作爲文本框
- 6. 如何在viemu(不使用箭頭鍵)的插入模式下移動光標?
- 7. textmate不使用箭頭鍵移動光標
- 8. Eclipse無需使用箭頭鍵左右/上/下移動光標
- 9. 如何向前移動文本光標?
- 10. 如何插入的文本的開頭光標在文本框使用WPF
- 11. 如何使用jQuery在使用向上和向下箭頭鍵的<section>標記之間移動?
- 12. 設置X11光標箭頭
- 13. 在使用javascript和兩個箭頭圖標的文本字段之間導航
- 14. 如何將光標移動到文本框中的文本框的前面?
- 15. macOS Sierra - 按住箭頭鍵時移動光標的方法
- 16. 如何用箭頭鍵移動矩形?
- 17. 如何將控件/光標移動到另一個文本框
- 18. PowerPoint:在rectantgle之間的動畫箭頭
- 19. 窗口7 64位:使用shift +向下箭頭和ctrl + shift +向左箭頭移動光標,但不選擇
- 20. 在UWP中自動移動光標到下一個文本框
- 21. 用箭頭鍵移動JFrame?
- 22. 用箭頭鍵移動JLabel
- 23. 用箭頭移動列
- 24. 在TextArea中移動文本光標Java
- 25. 從任何應用程序中獲取視圖以移動箭頭光標
- 26. 使用AutoKey腳本移動光標
- 27. 將鼠標光標更改爲箭頭
- 28. 如何使用箭頭鍵在GridWorld中移動一個Bug
- 29. 如何使用箭頭鍵在ASP.NET Gridview中上下移動
- 30. 如何使用javascript使用箭頭鍵移動對象
使用KeyPress。您可能還需要使用SelectionStart檢查光標位置 – David