how to move the cursor between textboxes using arr

2020-02-15 01:32发布

I have several textboxes, i want the cursor to move from one textbox to another using arrow keys.

how can i do that?

it looks like this, also the tap moves vertically which is weird.

Thanks.enter image description here

4条回答
乱世女痞
2楼-- · 2020-02-15 02:08

Just made this off the top of my head creatively. This will give you exactly what you want.

Step 1 create a TableLayoutPanel and make the columns 4 and the rows 5. Delete all your original text boxes and Step 2 add this to your code.

    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; }
             }
    }

This will allow you to navigate up down left right with the arrow keys and it will fix your issue with the tab so tab will now go right and shift+tab will go back. Additionally this solution is nice because if you go up or down it will cycle back around as you would intuitively expect. Also if you are feeling zesty you can move diagonally now.

查看更多
▲ chillily
3楼-- · 2020-02-15 02:08

Try handling the keypress event
→,← can force tab,shift+tab key press respectively.
Just a rough idea, as I have never tried this.

查看更多
smile是对你的礼貌
4楼-- · 2020-02-15 02:09

You can override the form's ProcessCmdKey function, and handle the key press and focusing on text boxes in it.

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;
                    }
                }
            }
        }
    }
}
查看更多
男人必须洒脱
5楼-- · 2020-02-15 02:09

The following solution works if there is some text in the text boxes.

First create a KeyDown event handler:

   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();
    }
 }
查看更多
登录 后发表回答