Вы должны обработать событие 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
.
Если вы хотите, чтобы обновить значение в 'TextBox', когда строка добавляется в' DataGridView', это не имело бы больше смысла попытаться подключиться к событию на сетке? –
Если вы хотите обновить его в текстовом поле? 'TextChanged' не является правильным местом –
Я хочу, чтобы textBox9 автоматически вычислял сумму независимо от того, сколько строк в Datagridview ... –