0
votes

I've got a form with a Textbox and a DataGridView with 1 row and 10 columns. When the user hits TAB on column #9, I want the focus to go to the next control on the form's tab order (the Textbox). To accomplish this, I override ProcessCmd with this code:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    const int WM_KEYDOWN = 0x100;
    const int WM_SYSKEYDOWN = 0x104;

    if ((msg.Msg == WM_KEYDOWN) || (msg.Msg == WM_SYSKEYDOWN))
    {
        switch (keyData & Keys.KeyCode)
        {
            case Keys.Tab:
            case Keys.Enter:
                if (this.CurrentCell != null && this.CurrentCell.ColumnIndex == 8)
                {
                    Form frmParent = FindForm();
                    frmParent.SelectNextControl(frmParent.ActiveControl, true, true, true, true);
                    return true;
                }
                break;
        }
    }
    return base.ProcessCmdKey(ref msg, keyData);
}

When I run this, it works fine if the cell is not in edit mode. However, if the cell is in edit mode, the focus leaves the grid but appears to go nowhere. It's not on the Textbox or the grid. But, if I then open up a new form and then switch back to this form, then the Textbox has focus. Or if I then hit Shift+Tab, the grid gets focus.

I'm making this as a grid that can work on any form which could have many other controls on it. This form is a prototype so it only has one other control.

Am I missing something?

1
Why don't you try to check in your switch case, if it is in the edit mode, try to save/cancel the changes first before executing frmParent.SelectNextControl(frmParent.ActiveControl, true, true, true, true); - Ruly
This code was simplified to focus on the problem I was having. The actual code validates and saves the changes before calling SelectNextControl. - Peter Ringering

1 Answers

2
votes

I solved the problem. What I did was call the DetatchEditingControl method of the CurrentCell just before calling SelectNextControl. See the code below:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    const int WM_KEYDOWN = 0x100;
    const int WM_SYSKEYDOWN = 0x104;

    if ((msg.Msg == WM_KEYDOWN) || (msg.Msg == WM_SYSKEYDOWN))
    {
        switch (keyData & Keys.KeyCode)
        {
            case Keys.Tab:
            case Keys.Enter:
                if (this.CurrentCell != null && this.CurrentCell.ColumnIndex == 8)
                {
                    if (this.EditingControl != null)
                        this.CurrentCell.DetachEditingControl();
                    Form frmParent = FindForm();
                    frmParent.SelectNextControl(frmParent.ActiveControl, true, true, true, true);
                    return true;
                }
                break;

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