Вы должны обработать событие 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
инициализации.
person
King King
schedule
13.11.2013
TextChanged
не то место - person Sriram Sakthivel   schedule 13.11.2013