C# 如何使用箭头键在文本框之间移动光标?

C# 如何使用箭头键在文本框之间移动光标?,c#,winforms,user-interface,user-controls,C#,Winforms,User Interface,User Controls,我有几个文本框,我希望光标使用箭头键从一个文本框移动到另一个 我该怎么做 看起来是这样的,而且水龙头垂直移动,这很奇怪 谢谢 如果文本框中有一些文本,则以下解决方案有效 首先创建一个KeyDown事件处理程序: private void textBoxLeft_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode.Equals(Keys.Right)) { e.Handled = true;

我有几个
文本框
,我希望光标使用箭头键从一个
文本框
移动到另一个

我该怎么做

看起来是这样的,而且水龙头垂直移动,这很奇怪

谢谢


如果文本框中有一些文本,则以下解决方案有效

首先创建一个
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();
    }
}

您可以重写表单的
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;
                    }
                }
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Windows.Forms;
命名空间文本框
{
公共部分类Form1:Form
{
列出文本框;
公共表格1()
{
初始化组件();
//获取二维结构以容纳文本框
这是._textboxs=新列表();
TextBox[]行1=新的TextBox[4];
行1[0]=textBox1;
行1[1]=文本框2;
行1[2]=文本框3;
行1[3]=文本框4;
TextBox[]行2=新的TextBox[4];
第2行[0]=文本框5;
第2行[1]=文本框6;
第2行[2]=文本框7;
第2行[3]=文本框8;
TextBox[]行3=新的TextBox[4];
第3行[0]=文本框9;
第3行[1]=文本框10;
第3行[2]=文本框11;
第3行[3]=文本框12;
TextBox[]行4=新的TextBox[4];
第4行[0]=文本框13;
第4行[1]=文本框14;
第4行[2]=文本框15;
第4行[3]=文本框16;
此._textboxs.Add(第1行);
此._textboxs.Add(第2行);
此._textboxs.Add(第3行);
此._textboxs.Add(第4行);
}
/// 
///处理命令键。
/// 
///通过引用传递的,表示要处理的Win32消息。
///表示进程的键的值之一。
/// 
///如果控件处理并使用了击键,则为true;否则为false以允许进一步处理。
/// 
受保护的覆盖bool ProcessCmdKey(参考消息消息消息,Keys keyData)
{
//按了一个键!
Control-activeCtrl=this.ActiveControl;
TextBox txb=activeCtrl作为TextBox;
//仅当文本框被聚焦时发送时才处理它
如果(txb!=null)
{
int行;
int列;
//找出当前处于活动状态的文本框
this.GetTextBoxIndexes(txb,out行,out列);
//根据键的笔划改变索引
if(keyData==Keys.Up)
{
行--;
}
else if(keyData==Keys.Down)
{
行++;
}
else if(keyData==Keys.Left)
{
列--;
}
else if(keyData==Keys.Right)
{
列++;
}
//确保我们没有处于负/超出ranfe指数
行=数学Abs(行+4)%4;
列=数学绝对值(列+4)%4;
//焦点请求文本框
TextBox slected=此项。_textboxs[行][列];
slected.Focus();
}
//别忘了不要打破锁链。。。
返回base.ProcessCmdKey(ref msg,keyData);
}
/// 
///获取文本框索引。
/// 
///纺织箱。
///行外索引。
///输出列索引。
私有void GetTextBoxIndexes(文本框txb、out int行、out int列)
{
行=-1;
列=-1;
对于(int-rowIdx=0;rowIdx
尝试处理按键事件
→,← 可以分别强制tab键、shift键和tab键。

这只是一个粗略的想法,因为我从来没有尝试过。

我只是创造性地把这个想法从我的脑海中抹去。这会给你你想要的

步骤1:创建一个
表格布局面板
,并使列4和行5。删除所有原始文本框

步骤2:将其添加到代码中

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; }
        }
    }
}
void tableLayoutPanel1\u KeyDown(对象发送器,KeyEventArgs e)
{//这会将长方体焦点向左或向右上下移动
if(e.KeyData==Keys.Left)
{
for(int i=0;itext.Length-1?0:i+1].Focus();break;}
}
}
else if(e.KeyData==Keys.Up)
{
for(int i=0;i