你必须处理事件CellValueChanged
。但是,您的方法有点糟糕,因为每次单元格的值发生变化时,您都必须遍历所有行以更新总和。您应该跟踪您的单元格更改以存储最后一个值,然后您可以轻松更新总和。最初需要使用循环计算总和。刚做了1次。
//This is used as CellTemplate for your interested column
public class TrackedValueDataGridViewCell : DataGridViewTextBoxCell {
public object OldValue { get; set; }
protected override bool SetValue(int rowIndex, object value) {
OldValue = Value;
return base.SetValue(rowIndex, value);
}
}
public partial class Form1 : Form {
public Form1(){
InitializeComponent();
//init your grid
dataGridView1.DataSource = yourDataSource;
dataGridView1.Columns["sumColumn"].CellTemplate = new TrackedValueDataGridViewCell();
sum = InitSum(dataGridView1,"sumColumn");
textBox9.Text = sum.ToString();
dataGridView1.CellValueChanged += (s,e) => {
if(dataGridView1.Columns[e.ColumnIndex].Name != "sumColumn") return;
var cell = ((TrackedValueDataGridViewCell) dataGridView1[e.ColumnIndex, e.RowIndex]);
sum -= ((double?) cell.OldValue).GetValueOrDefault();
sum += ((double?)cell.Value).GetValueOrDefault();
textBox9.Text = sum.ToString();
};
}
double sum;
public double InitSum(DataGridView grid, string colName) {
return grid.Rows.OfType<DataGridViewRow>()
.Sum(row => ((double?) row.Cells[colName].Value).GetValueOrDefault());
}
}
注意:我想你要总结的列是命名sumColumn
的,我们应该使用Name
引用列,因为它更具可读性。上面的代码不计算添加新行和从网格中删除现有行的情况。事实上,无论何时以编程方式添加和删除,您都应该sum
在添加和删除之前轻松更新。对于添加,我们可以处理RowsAdded
事件。以下所有事件处理程序注册都应放置在某个Form.Load
事件处理程序中:
dataGridView1.RowsAdded += (s, e) => {
for (int i = e.RowIndex; i < e.RowIndex + e.RowCount; i++) {
sum += ((double?)dataGridView1["sumColumn", i].Value).GetValueOrDefault();
}
textBox9.Text = sum.ToString();
};
但是对于删除行,这是非常棘手的。RowsRemoved
效果不好,我们不能再在事件处理程序中引用已删除的行,RowsRemoved
因此我们可能必须遍历所有行并更新总和:
dataGridView1.RowsRemoved += (s, e) => {
sum = InitSum(dataGridView1,"sumColumn");
textBox9.Text = sum.ToString();
};
这是为了按代码和用户删除行。另一个更好的选择是您必须处理UserDeletingRow
(但这仅适用于按用户删除行,而不是按代码)。要通过代码处理删除行,我认为您始终可以sum
在删除行的任何代码之前插入更新代码,这里是:
//for user removing rows
dataGridView1.UserDeletingRow += (s, e) => {
sum -= ((double?) e.Row.Cells["sumColumn"].Value).GetValueOrDefault();
textBox9.Text = sum.ToString();
};
//for code removing rows, use some method to remove rows like this:
public void RemoveRows(DataGridView grid, int startIndex, int count){
for(int i = startIndex; i <= startIndex + count; i++){
//update the sum first
sum -= ((double?)grid.Rows[i].Cells["sumColumn"].Value).GetValueOrDefault();
//then remove the row
grid.Rows.RemoveAt(startIndex);
}
textBox9.Text = sum.ToString();
}
请注意,所有事件处理程序都应在您的网格初始化后注册,并在初始化之后使用一些初始数据sum
。