带按钮控件的 DataGridView - 删除行
DataGridView with Button Control - Delete Row
我想在 DataGridView
的每一行末尾都有一个删除按钮,然后单击它我想从作为我的网格数据源的绑定列表中删除所需的行。
但我似乎做不到,我在产品 class 中创建了一个按钮对象,并使用唯一 ID 实例化它以从列表中删除该对象。但是行中没有显示按钮。
表单中有文本框,用户可以输入文本,当他们按下添加按钮时,将使用提供的字段实例化一个新的产品对象,然后将其添加到 BindingList
。
最后,此列表绑定到 DataGridView
,详细信息显示在网格中。 (这部分我已经做了)
最后单击保存按钮,列表将保存在数据库中。
public class Product{
public string Brand { get; set; }
public int ProductPrice { get; set; }
public int Quantity { get; set; }
public product(string brand,int productPrice, int quantity){
this.Brand = brand;
this.ProductPrice = productPrice;
this.Quantity = quantity;
}
}
public partial class MainForm: Form{
.....
BindingList<Product> lProd = new BindingList<Product>();
private void btnAddProduct_Click(object sender, EventArgs e){
string Brand = txtProBrand.Text;
int Price = Convert.ToInt32(txtPrice.Text);
int Quantity = Convert.ToInt32(txtQuantity.Text);
Product pro = new Product(Brand, Price, Quantity);
lProd.Add(pro);
dataGridView1.DataSource = null;
dataGridView1.DataSource = lProd;
}
.....
}
要在 DataGridView
行显示按钮,您应该向网格的列添加 DataGridViewButtonColumn
。以下是您在使用按钮栏时应该了解的一些常见任务:
- 将按钮列添加到 DataGridView
- 在按钮上显示图像
- 设置按钮的文本
- 处理按钮的点击事件
将按钮列添加到 DataGridView
要在网格的每一行上显示一个按钮,您可以通过编程方式或使用设计器将 DataGridViewButtonColumn
添加到网格的列中:
var deleteButton=new DataGridViewButtonColumn();
deleteButton.Name="dataGridViewDeleteButton";
deleteButton.HeaderText="Delete";
deleteButton.Text="Delete";
deleteButton.UseColumnTextForButtonValue=true;
this.dataGridView1.Columns.Add(deleteButton);
在按钮上显示图像
如果您更喜欢在按钮上绘制图像,您应该在资源中有一个图像,然后处理网格的 CellPainting
事件:
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;
}
}
设置按钮文字
您可以使用以下任一选项:
您可以设置 DataGridViewButtonColumn
的 Text
属性 并将其 UseColumnTextForButtonValue
设置为 true
,这样文本将显示在每个单元格上该专栏的。
deleteButton.Text="Delete";
deleteButton.UseColumnTextForButtonValue=true;
您也可以使用 Value
属性 单元格:
this.dataGridView1.Rows[1].Cells[0].Value = "Some Text";
作为另一种选择,您可以处理网格的 CellFormatting
事件。当你想为按钮设置不同的文本时,这种方式可能会有用。
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";
}
}
处理按钮的点击事件
要处理按钮的点击,您可以处理网格的 CellClick
or CellContentClick
事件。这两个事件都是通过单击和按 Space 键触发的。
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
}
}
获取点击事件记录的数据
你有e.RowIndex
,那么你可以得到行后面的数据:
var data = (Product)dataGridView1.Rows[e.RowIndex].DataBoundItem;
// then you can get data.Id, data.Name, data.Price, ...
您需要将其转换为 recore 的数据类型,例如 Product
。
如果数据绑定已设置为使用 DataTable,则要转换的类型为 DataRowView
。
您也可以使用 dataGridView1.Rows[e.RowIndex].Cells[some cell index].Value
来获取特定单元格的值,但是 DataBoundItem
更有意义。
备注
- 正如 Ivan 在评论中提到的,当您使用
BindingList
时,您不需要将网格的数据源设置为 null 并在每次更改时返回绑定列表。 BindingList
本身反映了对 DataGridView
的更改。
我想在 DataGridView
的每一行末尾都有一个删除按钮,然后单击它我想从作为我的网格数据源的绑定列表中删除所需的行。
但我似乎做不到,我在产品 class 中创建了一个按钮对象,并使用唯一 ID 实例化它以从列表中删除该对象。但是行中没有显示按钮。
表单中有文本框,用户可以输入文本,当他们按下添加按钮时,将使用提供的字段实例化一个新的产品对象,然后将其添加到 BindingList
。
最后,此列表绑定到 DataGridView
,详细信息显示在网格中。 (这部分我已经做了)
最后单击保存按钮,列表将保存在数据库中。
public class Product{
public string Brand { get; set; }
public int ProductPrice { get; set; }
public int Quantity { get; set; }
public product(string brand,int productPrice, int quantity){
this.Brand = brand;
this.ProductPrice = productPrice;
this.Quantity = quantity;
}
}
public partial class MainForm: Form{
.....
BindingList<Product> lProd = new BindingList<Product>();
private void btnAddProduct_Click(object sender, EventArgs e){
string Brand = txtProBrand.Text;
int Price = Convert.ToInt32(txtPrice.Text);
int Quantity = Convert.ToInt32(txtQuantity.Text);
Product pro = new Product(Brand, Price, Quantity);
lProd.Add(pro);
dataGridView1.DataSource = null;
dataGridView1.DataSource = lProd;
}
.....
}
要在 DataGridView
行显示按钮,您应该向网格的列添加 DataGridViewButtonColumn
。以下是您在使用按钮栏时应该了解的一些常见任务:
- 将按钮列添加到 DataGridView
- 在按钮上显示图像
- 设置按钮的文本
- 处理按钮的点击事件
将按钮列添加到 DataGridView
要在网格的每一行上显示一个按钮,您可以通过编程方式或使用设计器将 DataGridViewButtonColumn
添加到网格的列中:
var deleteButton=new DataGridViewButtonColumn();
deleteButton.Name="dataGridViewDeleteButton";
deleteButton.HeaderText="Delete";
deleteButton.Text="Delete";
deleteButton.UseColumnTextForButtonValue=true;
this.dataGridView1.Columns.Add(deleteButton);
在按钮上显示图像
如果您更喜欢在按钮上绘制图像,您应该在资源中有一个图像,然后处理网格的 CellPainting
事件:
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;
}
}
设置按钮文字
您可以使用以下任一选项:
您可以设置 DataGridViewButtonColumn
的 Text
属性 并将其 UseColumnTextForButtonValue
设置为 true
,这样文本将显示在每个单元格上该专栏的。
deleteButton.Text="Delete";
deleteButton.UseColumnTextForButtonValue=true;
您也可以使用 Value
属性 单元格:
this.dataGridView1.Rows[1].Cells[0].Value = "Some Text";
作为另一种选择,您可以处理网格的 CellFormatting
事件。当你想为按钮设置不同的文本时,这种方式可能会有用。
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";
}
}
处理按钮的点击事件
要处理按钮的点击,您可以处理网格的 CellClick
or CellContentClick
事件。这两个事件都是通过单击和按 Space 键触发的。
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
}
}
获取点击事件记录的数据
你有e.RowIndex
,那么你可以得到行后面的数据:
var data = (Product)dataGridView1.Rows[e.RowIndex].DataBoundItem;
// then you can get data.Id, data.Name, data.Price, ...
您需要将其转换为 recore 的数据类型,例如 Product
。
如果数据绑定已设置为使用 DataTable,则要转换的类型为 DataRowView
。
您也可以使用 dataGridView1.Rows[e.RowIndex].Cells[some cell index].Value
来获取特定单元格的值,但是 DataBoundItem
更有意义。
备注
- 正如 Ivan 在评论中提到的,当您使用
BindingList
时,您不需要将网格的数据源设置为 null 并在每次更改时返回绑定列表。BindingList
本身反映了对DataGridView
的更改。