简体   繁体   中英

How to select next control in winforms from code on TAB pressed inside a Datagridview

I have a strange problem. In Winforms app i have a datagridview where i implemented some code for moving inside of it with arrow keys and enter key...

class CalibDataGridView : System.Windows.Forms.DataGridView
    {
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            int row = 0;
            int col = 0;
            // return base.ProcessCmdKey(ref msg, keyData);
            switch (keyData)
            {
                case Keys.Down:
                    return true;
                case Keys.Up:
                    return true;

                case Keys.Right:
                    row = this.CurrentCell.RowIndex;
                    col = this.CurrentCell.ColumnIndex;

                    while (true)
                    {
                        col++;
                        if (col == this.Columns.Count)
                        {
                            row++;
                            col = 0;
                        }

                        if (row == this.Rows.Count)
                        {
                            col = 0;
                            row = 0;
                        }

                        if (!this[col, row].ReadOnly && this[col, row].Visible) break;
                    }

                    this.CurrentCell = this[col, row];

                    return true;

                case Keys.Left:
                    row = this.CurrentCell.RowIndex;
                    col = this.CurrentCell.ColumnIndex;

                    while (true)
                    {
                        col--;
                        if (col < 0)
                        {
                            row--;
                            col = this.Columns.Count - 1;
                        }

                        if (row < 0)
                        {
                            row = this.Rows.Count - 1;
                            col = this.Columns.Count - 1;
                        }

                        if (!this[col, row].ReadOnly && this[col, row].Visible) break;
                    }

                    this.CurrentCell = this[col, row];

                    return true;

                case Keys.Enter:
                    row = this.CurrentCell.RowIndex;
                    col = this.CurrentCell.ColumnIndex;

                    while (true)
                    {

                            row++;
                        if (row == this.Rows.Count)
                        {
                            row = 0;
                        }

                        if (!this[col, row].ReadOnly && this[col, row].Visible) break;
                    }

                    this.CurrentCell = this[col, row];

                    return true;

                default:
                    return base.ProcessCmdKey(ref msg, keyData);
            }
        }
    }

The code works fine, but i'm having a problem implement function to move to next control when TAB key is pressed. I added some code in PreviewKeyDown function of datagridview:

private void dgvRepeatability1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            if (e.KeyCode == Keys.PageDown && tbcMain.SelectedIndex > 0)
            {
                tbcMain.SelectedIndex--; //changes tab page
            }
            else if (e.KeyCode == Keys.PageUp && tbcMain.SelectedIndex < 7)
            {

                tbcMain.SelectedIndex++;
            }
            else if (e.KeyCode == Keys.Tab) //does not work like it should!!!!
            {
                Console.Beep(1000, 200);
                this.SelectNextControl((Control)sender, true, true, true, true);

            }
        }

This last code works in strange way... when triggered it somewhere in the background changes focus like it should (it beeps and the next control changes background color so i can see it is focused), but then i lose focus on the whole form... i can press TAB or ARROW KEYS or any other key and nothing happens....

If i minimize the form and then maximize it again the focus goes to the next control like it should in the first place and everything works like it should.

I also tryed change focus with .Select() and .Focus() and did not work.

Thanks in advance for help!

You can use SelectNextControl:

private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
{
    if ( e.KeyCode == Keys.Tab )
    {
        e.Handled = true; 
        this.SelectNextControl((Control)sender, true, true, true, true);
    }

You can also find the next control yourself:

private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
{
    if ( e.KeyCode == Keys.Tab )
    {
        e.Handled = true;
        var dataGrid = (DataGridView) sender;
        var tabIndex = dataGrid.TabIndex;
        var controls = this.Controls.Cast<Control>().Where( r => r.TabIndex > tabIndex );
        if ( controls.Any() )
        {
            controls.OrderBy(r => r.TabIndex).First().Select();
        }
        else
        {
            this.Controls.Cast<Control>()
                         .Where( r => r.TabIndex <= tabIndex )
                         .OrderBy( r => tabIndex )
                         .First()
                         .Select();
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM