how to move the cursor between textboxes using arrows?

和自甴很熟 提交于 2020-01-10 05:45:15

问题


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.


回答1:


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



回答2:


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



回答3:


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.




回答4:


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



来源:https://stackoverflow.com/questions/16909291/how-to-move-the-cursor-between-textboxes-using-arrows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!