Argv
Argv

Reputation: 41

Create Right Click Menu on dataGridView for entire row

I have a simple dataGridView filled with stuff, now I want to be able to right-click the left side to highlight the entire row so I can insert or delete entire row. I've been searching for this for a while, but most of the time it's for single cells, I'm looking for a context menu that is used on entire rows.

There is another question that is similar but ultimately not exactly what I'm trying to do.

Thank you in advance!!

Upvotes: 0

Views: 8549

Answers (1)

Argv
Argv

Reputation: 41

I found a pretty easy way to do what I wanted to do. It goes like this:

first of all, hook up a mouseDown event:

dataGridView1.MouseDown += new MouseEventHandler(this.dataGridView1_MouseClick);

then, create the routine co-responding to the mouseDown event..

 private void dataGridView1_MouseClick(Object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            ContextMenu cm = new ContextMenu();
            this.ContextMenu = cm;
            cm.MenuItems.Add(new MenuItem("&Cut", new System.EventHandler(this.cut_Click)));
            cm.MenuItems.Add(new MenuItem("&Copy", new System.EventHandler(this.copy2_Click)));
            cm.MenuItems.Add(new MenuItem("&Paste", new System.EventHandler(this.paste2_Click)));



            cm.Show(this, new Point(e.X, e.Y));
        }

    }

Then add your event routines, such as:

private void cut_Click(Object sender, EventArgs e)
    {
        if (this.dataGridView1.GetCellCount(DataGridViewElementStates.Selected) > 0)
        {
            try
            {
                Clipboard.SetDataObject(this.dataGridView1.GetClipboardContent());
            }
            catch (System.Runtime.InteropServices.ExternalException)
            {
                MessageBox.Show("Clipboard could not be accessed. Please try again.");
            }
        }

        if (this.dataGridView1.SelectedRows.Count > 0)
        {
            dataGridView1.Rows.RemoveAt(this.dataGridView1.SelectedRows[0].Index);
        }

    }

which will add the copied cells to the clip board. Then to paste them, something like:

private void paste2_Click(Object sender, EventArgs e)
    {
        char[] rowSplitter = { '\r', '\n' };
        char[] columnSplitter = { '\t' };

        // Get the text from clipboard
        IDataObject dataInClipboard = Clipboard.GetDataObject();
        string stringInClipboard = (string)dataInClipboard.GetData(DataFormats.Text);

        // Split it into lines
        string[] rowsInClipboard = stringInClipboard.Split(rowSplitter, StringSplitOptions.RemoveEmptyEntries);

        // Get the row and column of selected cell in grid
        int r = dataGridView1.SelectedCells[0].RowIndex;
        int c = dataGridView1.SelectedCells[0].ColumnIndex;

        // Add rows into grid to fit clipboard lines
        if (dataGridView1.Rows.Count < (r + rowsInClipboard.Length))
        {
            dataGridView1.Rows.Add(r + rowsInClipboard.Length - dataGridView1.Rows.Count);
        }

        // Loop through the lines, split them into cells and place the values in the corresponding cell.
        for (int iRow = 0; iRow < rowsInClipboard.Length; iRow++)
        {
            // Split row into cell values
            string[] valuesInRow = rowsInClipboard[iRow].Split(columnSplitter);

            // Cycle through cell values
            for (int iCol = 0; iCol < valuesInRow.Length; iCol++)
            {

                // Assign cell value, only if it within columns of the grid
                if (dataGridView1.ColumnCount - 1 >= c + iCol)
                {
                    DataGridViewCell cell = dataGridView1.Rows[r + iRow].Cells[c + iCol];

                    if (!cell.ReadOnly)
                    {
                        cell.Value = valuesInRow[iCol+1];
                    }
                }
            }
        }
    }

I use [col+1] because the first item in the list is always a blank (""). Hope this helps someone. It works for me! :D

Upvotes: 3

Related Questions