Datagridview with Button Control - Delete Row

DataGridView with Button Control - Delete Row

To show a button on DataGridView rows, you should add a DataGridViewButtonColumn to columns of your grid. Here is some common tasks which you should know when using button column:

  • Add Button Column to DataGridView
  • Show Image on Button
  • Set Text of Button
  • Handle Click Event of Button

Add Button Column to DataGridView

To show a button on each row of your grid, you can add a DataGridViewButtonColumn to columns of your grid programmatically or using designer:

var deleteButton=new DataGridViewButtonColumn();
deleteButton.Name="dataGridViewDeleteButton";
deleteButton.HeaderText="Delete";
deleteButton.Text="Delete";
deleteButton.UseColumnTextForButtonValue=true;
this.dataGridView1.Columns.Add(deleteButton);

Show Image on Button

If you prefer to draw image on button, you should have an image in a resource and then handle CellPainting event of your grid:

void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.RowIndex == dataGridView1.NewRowIndex || e.RowIndex < 0)
return;

if (e.ColumnIndex == dataGridView1.Columns["dataGridViewDeleteButton"].Index)
{
var image = Properties.Resources.DeleteImage; //An image
e.Paint(e.CellBounds, DataGridViewPaintParts.All);
var x = e.CellBounds.Left + (e.CellBounds.Width - image.Width) / 2;
var y = e.CellBounds.Top + (e.CellBounds.Height - image.Height) / 2;
e.Graphics.DrawImage(image, new Point(x, y));

e.Handled = true;
}
}

Set Text of Button

You can use either of these options:

You can set Text property of your DataGridViewButtonColumn and also set its UseColumnTextForButtonValue to true, this way the text will display on each cells of that column.

deleteButton.Text="Delete";
deleteButton.UseColumnTextForButtonValue=true;

Also you can use Value property of cell:

this.dataGridView1.Rows[1].Cells[0].Value = "Some Text";

Also as another option, you can handle CellFormatting event of your grid. This way may be useful when you want to set different texts for buttons.

void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
//If this is header row or new row, do nothing
if (e.RowIndex < 0 || e.RowIndex == this.dataGridView1.NewRowIndex)
return;

//If formatting your desired column, set the value
if (e.ColumnIndex=this.dataGridView1.Columns["dataGridViewDeleteButton"].Index)
{
e.Value = "Delete";
}
}

Handle Click Event of Button

To hanlde clicks on button, you can handle CellClick or CellContentClick event of your grid. Both events fires by click and by pressing Space key.

void dataGridView_CellClick(object sender, DataGridViewCellEventArgs e)
{
//if click is on new row or header row
if( e.RowIndex == dataGridView1.NewRowIndex || e.RowIndex < 0)
return;

//Check if click is on specific column
if( e.ColumnIndex == dataGridView1.Columns["dataGridViewDeleteButton"].Index)
{
//Put some logic here, for example to remove row from your binding list.
//yourBindingList.RemoveAt(e.RowIndex);

// Or
// var data = (Product)dataGridView1.Rows[e.RowIndex].DataBoundItem;
// do something
}
}

Get data of the record on Click event

You have e.RowIndex, then you can get the data behind the row:

 var data = (Product)dataGridView1.Rows[e.RowIndex].DataBoundItem;
// then you can get data.Id, data.Name, data.Price, ...

You need to cast it to the data type of the recore, for example let's say Product.

If the data binding has been setup to use a DataTable, the the type to cast is DataRowView.

You can also use dataGridView1.Rows[e.RowIndex].Cells[some cell index].Value to get value of a specific cell, however DataBoundItem makes more sense.

Note

  • As mentioned by Ivan in comments, when you use BindingList you don't need to set datasource of grid to null and back to binding list with every change. The BindingList itself reflects changes to your DataGridView.

Delete Row from datagridview using button en each row

A delete command issued as constructor for a OleDbDataAdapter is not correct. However the adapter will execute the command nevertheless. But surely you cannot expect a delete command to be used to fill a datatable.

You still need a SELECT.

Usually this is done removing the row from the grid (this marks the underlying row as deleted then, when you want to save the changes to the database, you should use the orginal DataAdapter and the original DataTable used to initially fill the grid to issue the Update method

This is well explained here Using OleDbDataAdapter to Update a DataTable

Or you could do the update yourself using a separate command and reloading the datatable

// Delete the record on the db
empid = Convert.ToString(dataGridView1.Rows[e.RowIndex].Cells["empid"].Value);
OleDbCommand cmd = new OleDbCommand("delete from apps where appsid= @id", con);
cmd.Parameters.Add("@id", OleDbType.VarWChar).Value = empid;
cmd.ExecuteNonQuery();

// reload the grid with the updated info from the db
OleDbDataAdapter da = new OleDbDataAdapter("Select * from apps", con);
DataTable dt = new DataTable();
da.Fill(dt);
dataGridView1.DataSource = dt;
dataGridView1.Refresh();

This of course has the drawback to hit two times the database and reloading everything each time you delete a row.

how to delete row from datagridview with a delete button?

The source must be this: "when the datagridview loses focus it changes the current row to the last data row". This is not the normal case, you must be doing something (keybd events?) to make that happen.

I have made delete buttons under a Grid and they worked fine.

Edit: After clarification, it is about the special status of the 'New Row', it is kind of virtual. I sort of see the reasoning behind that, suppose the selection didn't shift back when leaving the Grid. The CurrentRow would be null. In your case that would be OK, but often it wouldn't.

One idea: track the Current property (BindingSource) and disable the Delete button if no Row is current. Check how it works when a new row is (half) filled.

And otherwise, Jeff's idea looks good too. Or see BFree's answer on this question.

How to trap delete row ( from keyboard ) in datagridview?

Attach to the UserDeletingRow event, and cancel the deletion (when required) by setting e.Cancelled = true

C# Remove element from List in DataGridView with button works only once

I'm using only 2 columns and form my DataGridView Design MetroUI framework, so I don't need to check if my column index is 1, because it is impossible to click column 0, which is used to edit numbers.

So it's enough to delete my elements just right that:

private void DrawGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex < 0)
return;

createdMap.RemoveAt(e.RowIndex);
DrawGrid.DataSource = createdMap.ToList();
}

According to @RezaAghaei answer this is better idea:

private void MultisetGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex < 0)
return;

if (e.ColumnIndex == 1)
{
createdMap.RemoveAt(e.RowIndex);
DrawGrid.DataSource = null;
DrawGrid.DataSource = createdMap;
}

}

Creating DataGridViewButtonCell to delete item of DataGridView?

Done. Finally I did what I wanted.

I did.

private void setDataSource(){
//added column with image before set datasource
if (grid.Columns["Del"] == null) {
var col = new DataGridViewImageColumn();
col.HeaderText = "";
col.Name = "Del";
col.Image = TerminalControleDeVendas.Properties.Resources.trash;
grid.Columns.Add(col);
}
grid.DataSource = ivDAO.findAllItemVenda(venda);
grid.ClearSelection();
defineGrid();
}

private void defineGrid() {
//header
grid.Columns["produto"].HeaderText = "Produto";
grid.Columns["valorUn"].HeaderText = "Unit.R$";
grid.Columns["quantidade"].HeaderText = "Qtd.";
grid.Columns["total"].HeaderText = "Total R$";

//hide
grid.Columns["id"].Visible = false;
grid.Columns["venda"].Visible = false;

//width
grid.Columns["Del"].Width = 30;
grid.Columns["produto"].Width = 220;
grid.Columns["valorUn"].Width = 80;
grid.Columns["quantidade"].Width = 50;
grid.Columns["total"].Width = 80;

//align
grid.Columns["valorUn"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
grid.Columns["quantidade"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
grid.Columns["total"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;

}

Finally I added the handler to delete item

private void grid_CellContentClick(object sender, DataGridViewCellEventArgs e) {
if (this.grid.Columns[e.ColumnIndex].Name == "Del") {
DialogResult confirma = MessageBox.Show("Deseja realmente excluir o item ?", "Excluir", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (confirma == DialogResult.Yes) {
ItemVenda iv = (ItemVenda)grid.CurrentRow.DataBoundItem;
ivDAO.delete(iv);
}
}
}

The result is

Sample Image

Delete a row in DataGridView Control in VB.NET

For Each row As DataGridViewRow In yourDGV.SelectedRows
yourDGV.Rows.Remove(row)
Next

This will delete all rows that had been selected.



Related Topics



Leave a reply



Submit