在 WinForms 中,DataGridView
控件提供了多个事件来响应单元格的变化。这些事件允许你在用户编辑单元格内容时执行特定的操作。以下是一些常见的 DataGridView
单元格改变触发的事件及其说明和使用示例:
常见的单元格改变事件
-
CellValueChanged - 当单元格的值改变时触发。
csharp
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) { if (e.RowIndex >= 0 && e.ColumnIndex >= 0) { MessageBox.Show($"单元格 ({e.RowIndex}, {e.ColumnIndex}) 的值已改变"); } }
-
CellValueNeeded - 当需要显示单元格的值时触发(适用于虚拟模式)。
csharp
private void dataGridView1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e) { // 提供单元格的值 e.Value = $"Value at ({e.RowIndex}, {e.ColumnIndex})"; }
-
CellValuePushed - 当单元格的值被修改时触发(适用于虚拟模式)。
csharp
private void dataGridView1_CellValuePushed(object sender, DataGridViewCellValueEventArgs e) { // 处理单元格值的修改 MessageBox.Show($"单元格 ({e.RowIndex}, {e.ColumnIndex}) 的值被修改为 {e.Value}"); }
-
CellBeginEdit - 当单元格开始编辑时触发。
csharp
private void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) { MessageBox.Show($"单元格 ({e.RowIndex}, {e.ColumnIndex}) 开始编辑"); }
-
CellEndEdit - 当单元格结束编辑时触发。
csharp
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) { MessageBox.Show($"单元格 ({e.RowIndex}, {e.ColumnIndex}) 结束编辑"); }
-
EditingControlShowing - 当编辑控件显示时触发。
csharp
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) { if (dataGridView1.CurrentCell.ColumnIndex == 1) { // 假设第二列需要特殊处理 TextBox textBox = e.Control as TextBox; if (textBox != null) { textBox.KeyPress += new KeyPressEventHandler(textBox_KeyPress); } } } private void textBox_KeyPress(object sender, KeyPressEventArgs e) { if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar)) { e.Handled = true; } }
示例代码
以下是一个完整的示例,展示了如何在 WinForms 中使用这些 DataGridView
单元格改变事件。
1. 设计窗体
在设计器中添加一个 DataGridView
控件和一个 Label
控件用于显示合计数量。
2. 编写代码
csharp
using System;
using System.Data;
using System.Windows.Forms;
public partial class Form1 : Form {
private DataTable dataTable;
public Form1() {
InitializeComponent();
InitializeDataGridView();
LoadData();
}
private void InitializeDataGridView() {
dataTable = new DataTable();
dataTable.Columns.Add("ProductID", typeof(int));
dataTable.Columns.Add("ProductName", typeof(string));
dataTable.Columns.Add("Quantity", typeof(int));
dataGridView1.DataSource = dataTable;
// 添加事件处理程序
dataGridView1.CellValueChanged += new DataGridViewCellEventHandler(dataGridView1_CellValueChanged);
dataGridView1.CellBeginEdit += new DataGridViewCellCancelEventHandler(dataGridView1_CellBeginEdit);
dataGridView1.CellEndEdit += new DataGridViewCellEventHandler(dataGridView1_CellEndEdit);
dataGridView1.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler(dataGridView1_EditingControlShowing);
}
private void LoadData() {
// 模拟从数据库加载数据
dataTable.Rows.Add(1, "Product A", 10);
dataTable.Rows.Add(2, "Product B", 20);
dataTable.Rows.Add(3, "Product C", 30);
CalculateTotalQuantity();
}
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
if (e.RowIndex >= 0 && e.ColumnIndex >= 0) {
MessageBox.Show($"单元格 ({e.RowIndex}, {e.ColumnIndex}) 的值已改变");
CalculateTotalQuantity();
}
}
private void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) {
MessageBox.Show($"单元格 ({e.RowIndex}, {e.ColumnIndex}) 开始编辑");
}
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) {
MessageBox.Show($"单元格 ({e.RowIndex}, {e.ColumnIndex}) 结束编辑");
}
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) {
if (dataGridView1.CurrentCell.ColumnIndex == 2) { // 假设第三列(Quantity)需要限制输入为数字
TextBox textBox = e.Control as TextBox;
if (textBox != null) {
textBox.KeyPress -= new KeyPressEventHandler(textBox_KeyPress);
textBox.KeyPress += new KeyPressEventHandler(textBox_KeyPress);
}
}
}
private void textBox_KeyPress(object sender, KeyPressEventArgs e) {
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar)) {
e.Handled = true;
}
}
private void CalculateTotalQuantity() {
int totalQuantity = 0;
foreach (DataGridViewRow row in dataGridView1.Rows) {
if (!row.IsNewRow) {
int quantity = 0;
if (int.TryParse(row.Cells["Quantity"].Value?.ToString(), out quantity)) {
totalQuantity += quantity;
}
}
}
labelTotalQuantity.Text = $"合计数量: {totalQuantity}";
}
}
解释
-
InitializeDataGridView 方法:
- 初始化
DataTable
并添加列。 - 将
DataTable
设置为DataGridView
的数据源。 - 添加事件处理程序以响应单元格变化。
- 初始化
-
LoadData 方法:
- 模拟从数据库加载数据。
- 调用
CalculateTotalQuantity
方法计算并显示合计数量。
-
CellValueChanged 事件:
- 当单元格的值改变时触发。
- 显示消息框提示单元格已改变。
- 调用
CalculateTotalQuantity
方法重新计算合计数量。
-
CellBeginEdit 事件:
- 当单元格开始编辑时触发。
- 显示消息框提示单元格开始编辑。
-
CellEndEdit 事件:
- 当单元格结束编辑时触发。
- 显示消息框提示单元格结束编辑。
-
EditingControlShowing 事件:
- 当编辑控件显示时触发。
- 检查当前编辑的列是否为
Quantity
列。 - 为
TextBox
添加KeyPress
事件处理程序以限制输入为数字。
-
textBox_KeyPress 方法:
- 限制
TextBox
输入为数字。 - 如果输入的字符不是数字或控制字符(如退格键),则忽略该字符。
- 限制
-
CalculateTotalQuantity 方法:
- 遍历
DataGridView
的每一行。 - 检查行是否为新行(
IsNewRow
属性)。 - 尝试将
Quantity
列的值解析为整数,并累加到totalQuantity
。 - 更新
labelTotalQuantity
的文本以显示合计数量。
- 遍历
注意事项
- 列名:确保
DataGridView
中的列名与DataTable
中的列名一致。 - 事件处理程序:确保正确添加事件处理程序,以避免事件未触发。
- 异常处理:在实际应用中,建议添加异常处理以应对数据解析失败或其他异常情况。
通过以上步骤和代码示例,你可以在 WinForms 应用程序中实现对 DataGridView
单元格变化的响应,并根据需要执行特定的操作。