13

I need to select a row in a DataGridView with right click before a ContextMenu is shown because the ContextMenu is row-dependent.

I've tried this:

 if (e.Button == MouseButtons.Right)
 {
     var hti = dataGrid.HitTest(e.X, e.Y);
     dataGrid.ClearSelection();
     dataGrid.Rows[hti.RowIndex].Selected = true;
 }

or:

private void dataGrid_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        dataGrid.Rows[e.RowIndex].Selected = true;
        dataGrid.Focus();
    }
}

This works but when I try to read dataGrid.Rows[CurrentRow.Index] I see only the row selected with left click and not those selected with right click.

jordanz
  • 367
  • 4
  • 12
user2396911
  • 163
  • 1
  • 1
  • 9

4 Answers4

32

Try setting the current cell like this (this will set the CurrentRow property of the DataGridView before the context menu item is selected):

    private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
    {
        var dataGrid = (DataGridView) sender;
        if (e.Button == MouseButtons.Right && e.RowIndex != -1)
        {
            var row = dataGrid.Rows[e.RowIndex];
            dataGrid.CurrentCell = row.Cells[e.ColumnIndex == -1 ? 1 : e.ColumnIndex];
            row.Selected = true;
            dataGrid.Focus();
        }
    }
Benj
  • 31,668
  • 17
  • 78
  • 127
Gjeltema
  • 4,122
  • 2
  • 24
  • 31
3

I realize this thread is old, I just wanted to add one thing: If you want to be able to select, and perform the action, on multiple rows: you can check to see if the row you are right-clicking is already selected. This way the DataGridview behaves likes a ListView in this regard. So right clicking on a row not already selected: selects this row and open the context menu. Right clicking on a row already selected just gives you the context menu and keep the selected rows as expected.

 private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
    {
        if (e.RowIndex != -1 && e.ColumnIndex != -1)
        {
            if (e.Button == MouseButtons.Right)
            {
                DataGridViewRow clickedRow = (sender as DataGridView).Rows[e.RowIndex]; 
                if (!clickedRow.Selected)
                    dataGridView1.CurrentCell = clickedRow.Cells[e.ColumnIndex];

                var mousePosition = dataGridView1.PointToClient(Cursor.Position);

                ContextMenu1.Show(dataGridView1, mousePosition);
            }
        }
    }
Rhys Jones
  • 5,348
  • 1
  • 23
  • 44
David Wakeman
  • 113
  • 1
  • 1
  • 6
0
    private void grid_listele_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            grid_listele.ClearSelection();
            grid_listele[e.ColumnIndex, e.RowIndex].Selected = true;
        }


    }
  • Can you add explanation as to why the OP's example were not working and what you did works? – Yogesh May 21 '14 at 21:32
0
 if (e.Button == System.Windows.Forms.MouseButtons.Right)
        {
            var hti = GridView.HitTest(e.X, e.Y);
            GridView.ClearSelection();

            int index = hti.RowIndex;

            if (index >= 0)
            {
                GridView.Rows[hti.RowIndex].Selected = true;
                LockFolder_ContextMenuStrip.Show(Cursor.Position);
            }

        }

This is Accurate Method i Guess

H2Five
  • 33
  • 8