Search code examples
c#visual-studio-2010datagridviewcontextmenustrip

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


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;
        }
    }

Solution

  • 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.
    }