1

Column 0 in a DataGridView control is Read Only. I want the focus to move to column 1 if the user selects column 0 with the mouse or presses the tab key from the last column in the previous row. I tried the following code in the CellEnter event but it causes an exception "Operation is not valid because it results in a reentrant call to the CurrentCellAddressCore function". Column 1 is named "patternsTerminator".

private void dataGridView_patterns_CellEnter(object sender, DataGridViewCellEventArgs e)
{
    int currentRow = e.RowIndex;

    try
    {
        if (this.dataGridView_patterns.CurrentCell.ColumnIndex == 0)
            this.dataGridView_patterns.CurrentCell = this.dataGridView_patterns.Rows[currentRow].Cells["patternsTerminator"];
    }
    catch (Exception ex)
    {
        MessageBox.Show(this, ex.Message, errCaption, button, icon);
    }
}

I understand why the exception occurs. When the focus moves to column 1, the CellEnter event is called again, and the exception prevents recursive calls to the CellEnter event.

I tried the following as a workaround but it ignores the tab key. When I click in column 0, SendKeys is called but the cursor stays in column 0.

if (this.dataGridView_patterns.CurrentCell.ColumnIndex == 0)
    SendKeys.Send("{TAB}");

I have read many of the threads on this and other websites but can't get it to work. Any suggestions would be greatly appreciated.

Thank you!

Dan Z
  • 101
  • 13
  • 1
    This is really what you want... https://stackoverflow.com/questions/751981/bypass-read-only-cells-in-datagridview-when-pressing-tab-key – AQuirky Jul 07 '17 at 03:32
  • Thanks, AQuirky, I read that thread before opening this one and could not get any of the suggestions to work. I even posted here that it appeared to ignore the tab character passed to SendKeys(). There are a lot of different answers on that thread. Is there one in particular that you think I should concentrate on? – Dan Z Jul 07 '17 at 21:44

2 Answers2

1

I got around the exception but the focus doesn't work right - for me it wants to skip the 2nd column with the following code. I ran out of time. Play around with that and if you can't get it I will follow up soon.

private void DgNew_CellEnter(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == 0)
    {
        this.BeginInvoke(new MethodInvoker(() =>
        {
            moveCellTo(dgNew, e.RowIndex, 1);
        }));
    }
}

private void moveCellTo(DataGridView dgCurrent, int rowIndex, int columnIndex)
{
    dgCurrent.CurrentCell = dgCurrent.Rows[rowIndex].Cells[columnIndex];
}

I got the idea from this post: How to evade reentrant call to setCurrentCellAddressCore?

jaredbaszler
  • 3,941
  • 2
  • 32
  • 40
  • That's brilliant, Jared. I only had to change dgNew to the name of my control and it works perfectly. I actually want the cursor to go to the second column (columnIndex = 1) when the first column (columnIndex = 0) has the focus. I'm not sure if that's what you meant by the 2nd column since columnIndex is 0 based. Thanks so much for the solution! – Dan Z Jul 07 '17 at 21:58
0

Adding to Jared's answer, I tested the following code and it works. The only difference between this and Jared's answer is that columnIndex is referred to by its name instead of by its index value. Thanks again, Jared.

        try
        {
            // Display the pattern number in column 0
            this.dataGridView_patterns.Rows[currentRow].Cells["patternNumber"].Value = currentRow + 1;

            // Move the current cell focus to column 1 (Terminator pattern) on current row
            if (e.ColumnIndex == 0)
            {
                this.BeginInvoke(new MethodInvoker(() =>
                {
                    moveCellTo(dataGridView_patterns, e.RowIndex, "patternsTer");
                }));
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(this, ex.Message, errCaption, button, icon);
        }
    }

    private void moveCellTo(DataGridView dgCurrent, int rowIndex, string columnName)
    {
        dgCurrent.CurrentCell = dgCurrent.Rows[rowIndex].Cells[columnName];
    }
Dan Z
  • 101
  • 13