How to identify dataGridView cell that was right clicked on for ContextMenuStrip?

12,898

Solution 1

You could keep track of whichever cell was last clicked by adding an event handler for the DataGridView's mouse click.

Something like:

    DataGridViewCell clickedCell;

    private void dataGridView1_CellMouseClick_1(object sender, DataGridViewCellMouseEventArgs e)
{
        try
    {
        DataGridView view = (DataGridView)sender;

        if (e.Button == System.Windows.Forms.MouseButtons.Right && e.RowIndex >= 0)
        {
            Console.WriteLine("Clicked column " 
                       + e.ColumnIndex + ", row " 
                       + e.RowIndex + " of DataGridView " 
                       + view.Name + " at " 
                       + System.Windows.Forms.Cursor.Position);

           clickedCell = view.Rows[e.RowIndex].Cells[e.ColumnIndex];
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
    }
}

Then in your contextMenuStripItem click event, switch on clickedCell.Value like:

switch (clickedCell.Value)
        {
            case "Copy":
            break;
... // etc.
}

Solution 2

You can do this using a HitTest with the datagridview.

This is an example of code that I have used.

        DataGridView dgv= (DataGridView)sender;
        if (e.Button == System.Windows.Forms.MouseButtons.Right)
        {
            try
            {
                dgv.CurrentCell = dgv[gvw.HitTest(e.X, e.Y).ColumnIndex, dgv.HitTest(e.X, e.Y).RowIndex];
            }
        }

You can then use the DGV.CurrentCell to find all the information.

switch ""
{
    case ""
      break;
}
Share:
12,898
PHBeagle
Author by

PHBeagle

Updated on June 15, 2022

Comments

  • PHBeagle
    PHBeagle almost 2 years

    User right clicks on a cell within a DGV, then makes a selection in the ContextMenuStrip. Based on their CMS selection, I want to do something (copy, hide, filter). My problem is identifying the cell that was right clicked on.

    I was trying to handle this scenario with the following method, but [ColumnIndex] cannot be referenced.

    private void cmsDataGridView_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            switch (e.ClickedItem.Text)
            {
                case "Copy":
                    break;
                case "Filter On":
                    break;
                case "Hide Column":
                    DataGridViewBand band = dataGridView1.Columns[e.ColumnIndex];
                    band.Visible = false;
                    break;
            }
        }
    

    Should I be doing this in two different methods? One to handle the mouse click (in which I could then capture the DGV column index), then from within there, I call the CMS item clicked event?

    Thank you for your help, Brian.


    The code that works for me. Oh and I did have to remove the cmsDataGridView method from the ContextMenuStrip property of the dataGridView within the designer. Leaving that in there caused problems.

                // Identify the cell clicked for cmsDataGridView
        DataGridViewCell clickedCell;
        private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            try
            {
                if (e.Button == MouseButtons.Right)
                {
                    dataGridView1.ClearSelection();
                    clickedCell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
                    clickedCell.Selected = true;
                    cmsDataGridView.Show(dataGridView1, e.Location);
                }
    
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
            }
        }
    
        private void cmsDataGridView_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            switch (e.ClickedItem.Text)
            {
                case "Copy":
                    break;
                case "Filter On":
                    break;
                case "Hide Column":
                    DataGridViewBand band = dataGridView1.Columns[clickedCell.ColumnIndex];
                    band.Visible = false;
                    break;
            }
        }
    
  • PHBeagle
    PHBeagle about 11 years
    Thank you. I'll modify my question with the answer that was a variation of Gojiria's. I started with the mouseClick event that Seige suggested, but I did want to contain my code to the DGV only. Thank you both. Unfortunately, my status is too low to give either of you a vote up.