Question

I have few columns in my DataGridView, and there is data in my rows. I saw few solutions in here, but I can not combine them!

Simply a way to right-click on a row, it will select the whole row and show a menu with an option to delete the row and when the option selected it will delete the row.

I made few attempts but none is working and it looks messy. What should I do?

Was it helpful?

Solution

I finally solved it:

  • In Visual Studio, create a ContextMenuStrip with an item called "DeleteRow"

  • Then at the DataGridView link the ContextMenuStrip

Using the code below helped me getting it work.

this.MyDataGridView.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MyDataGridView_MouseDown);
this.DeleteRow.Click += new System.EventHandler(this.DeleteRow_Click);

Here is the cool part

private void MyDataGridView_MouseDown(object sender, MouseEventArgs e)
{
    if(e.Button == MouseButtons.Right)
    {
        var hti = MyDataGridView.HitTest(e.X, e.Y);
        MyDataGridView.ClearSelection();
        MyDataGridView.Rows[hti.RowIndex].Selected = true;
    }
}

private void DeleteRow_Click(object sender, EventArgs e)
{
    Int32 rowToDelete = MyDataGridView.Rows.GetFirstRow(DataGridViewElementStates.Selected);
    MyDataGridView.Rows.RemoveAt(rowToDelete);
    MyDataGridView.ClearSelection();
}

OTHER TIPS

For completness of this question, better to use a Grid event rather than mouse.

First Set your datagrid properties:

SelectionMode to FullRowSelect and RowTemplate / ContextMenuStrip to a context menu.

Create the CellMouseDown event:-

private void myDatagridView_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        int rowSelected = e.RowIndex;
        if (e.RowIndex != -1)
        {
            this.myDatagridView.ClearSelection();
            this.myDatagridView.Rows[rowSelected].Selected = true;
        }
        // you now have the selected row with the context menu showing for the user to delete etc.
    }
}
private void dgvOferty_CellContextMenuStripNeeded(object sender, DataGridViewCellContextMenuStripNeededEventArgs e)
    {
        dgvOferty.ClearSelection();
        int rowSelected = e.RowIndex;
        if (e.RowIndex != -1)
        {
            this.dgvOferty.Rows[rowSelected].Selected = true;
        }
        e.ContextMenuStrip = cmstrip;
    }

TADA :D. The easiest way period. For custom cells just modify a little.

It's much more easier to add only the event for mousedown:

private void MyDataGridView_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        var hti = MyDataGridView.HitTest(e.X, e.Y);
        MyDataGridView.Rows[hti.RowIndex].Selected = true;
        MyDataGridView.Rows.RemoveAt(rowToDelete);
        MyDataGridView.ClearSelection();
    }
}

This is easier. Of cource you have to init your mousedown-event as already mentioned with:

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

in your constructor.

All the answers posed in to this question are based on a mouse click event. You can also assign a ContenxtMenuStrip to your DataGridview and check if there is a row selected when the user RightMouseButtons on the DataGridView and decide whether you want to view the ContenxtMenuStrip or not. You can do so by setting the CancelEventArgs.Cancel value in the the Opening event of the ContextMenuStrip

    private void MyContextMenuStrip_Opening(object sender, CancelEventArgs e)
    {
        //Only show ContextMenuStrip when there is 1 row selected.
        if (MyDataGridView.SelectedRows.Count != 1) e.Cancel = true;
    }

But if you have several context menu strips, with each containing different options, depending on the selection, I would go for a mouse-click-approach myself as well.

base on @Data-Base answer it will not work until make selection mode FullRow

  MyDataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;

but if you need to make it work in CellSelect Mode

 MyDataGridView.SelectionMode = DataGridViewSelectionMode.CellSelect;

 // for cell selection
 private void MyDataGridView_MouseDown(object sender, MouseEventArgs e)
 {
  if(e.Button == MouseButtons.Right)
    {
       var hit = MyDataGridView.HitTest(e.X, e.Y);
       MyDataGridView.ClearSelection();

       // cell selection
       MyDataGridView[hit.ColumnIndex,hit.RowIndex].Selected = true;
   }
}

private void DeleteRow_Click(object sender, EventArgs e)
{
   int rowToDelete = MyDataGridView.Rows.GetFirstRow(DataGridViewElementStates.Selected);
   MyDataGridView.Rows.RemoveAt(rowToDelete);
   MyDataGridView.ClearSelection();
}
private void MyDataGridView_MouseDown(object sender, MouseEventArgs e)
{
    if(e.Button == MouseButtons.Right)
    {
        MyDataGridView.ClearSelection();
        MyDataGridView.Rows[e.RowIndex].Selected = true;
    }
}

private void DeleteRow_Click(object sender, EventArgs e)
{
    Int32 rowToDelete = MyrDataGridView.Rows.GetFirstRow(DataGridViewElementStates.Selected);
    MyDataGridView.Rows.RemoveAt(rowToDelete);
    MyDataGridView.ClearSelection();
}

You can also make this a little simpler by using the following inside the event code:

private void MyDataGridView_MouseDown(object sender, MouseEventArgs e) 
{     
    if (e.Button == MouseButtons.Right)     
    {         
        rowToDelete = e.RowIndex;
        MyDataGridView.Rows.RemoveAt(rowToDelete);         
        MyDataGridView.ClearSelection();     
    } 
}

See here it can be done using the DataGridView RowTemplate property.

Note: This code isn't tested but I've used this method before.

// Create DataGridView
DataGridView gridView = new DataGridView();
gridView.AutoGenerateColumns = false;
gridView.Columns.Add("Col", "Col");

// Create ContextMenu and set event
ContextMenuStrip cMenu = new ContextMenuStrip();
ToolStripItem mItem = cMenu.Items.Add("Delete");
mItem.Click += (o, e) => { /* Do Something */ };           

// This makes all rows added to the datagridview use the same context menu
DataGridViewRow defaultRow = new DataGridViewRow();
defaultRow.ContextMenuStrip = cMenu;

And there you go, as easy as that!

I have a new workaround to come in same result, but, with less code. for Winforms... That's example is in portuguese Follow up step by step

  1. Create a contextMenuStrip in your form and create one item
  2. Sign one event click (OnCancelarItem_Click) for this contextMenuStrip enter image description here
  3. Create a event 'UserDeletingRow' on gridview enter image description here and now... you've simulating on key press del from user

    you don't forget to enable delete on the gridview, right?!

enter image description here enter image description here and finally... enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top