1
votes

I've read a few questions asking how to achieve DataGridRow selection when there's a right-click on the grid. The answers show a few different ways to achieve it and, for most part, they've worked for me except for this weird bug.

The row appears to be selected but unless the row is left-clicked first, the first row is always the row selected when the action is chosen. i.e. When I click edit on row 3, row 1's data will be passed to the edit form (unless I left click row 3 before right-clicking it)

This is the right-click menu showing the apparent selection:

enter image description here

Notice the little indicator is still on the first row.

If I dismiss the context menu, the row looks selected but is not:

enter image description here

If I left-click the same row it is now selected

enter image description here

Here's the code for the right-click event:

Designer code:

MyDataGrid.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MyDataGridView_MouseDown);

Form code:

private void MyDataGridView_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {       
        var hti = MyDataGrid.HitTest(e.X, e.Y);
        MyDataGrid.CurrentCell = MyDataGrid.Rows[hti.RowIndex].Cells[hti.ColumnIndex];
    }
}

What am I missing to actually select the row?

3
As an option you can simply assign a ContextMenuStrip to a row. Also if you want the row get selected before showing the menu, you can handle CellContextMenuStripNeeded event. It seems this post is what you are looking for. - Reza Aghaei

3 Answers

2
votes

Replace your code in the MouseDown event call back with this:

private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        var hti = dataGridView1.HitTest(e.X, e.Y);

        if (hti.RowIndex != -1)
        {
            dataGridView1.ClearSelection();
            dataGridView1.Rows[hti.RowIndex].Selected = true;
            dataGridView1.CurrentCell = dataGridView1.Rows[hti.RowIndex].Cells[0];
        }
    }
}

Here's a demonstration of it working:

enter image description here

0
votes

You can make the right clicked row the focused row in the CellMouseDown event like this

if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
     DataGridView1.CurrentCell = DataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
}
-1
votes

This is because right-click does not actually select the cell you've right-clicked on, only the left-click does this. You need to add a handler for the cell mouse down event, add this to your form's designer:

MyDataGridView.CellMouseDown += new System.Windows.Forms.MouseEventHandler(this.MyDataGridView_MouseDown);

And add this to your form's class:

private void MyDataGridView_MouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
    MyDataGridView.CurrentCell = MyDataGridView(e.ColumnIndex, e.RowIndex);
}

This will set the CurrentCell a.k.a. The cell that's currently selected to whichever cell the cursor was over when the MouseDown event was called.