winforms datagridview calculated field change even

2020-03-24 04:39发布

I have a datagridview bound from a datatable. I have a calculated column linetotal that multiples unitprice * quantity.

I also have a totalprice label,that I would like to contain the sum of the linetotal column in the datagridview.

When the user makes any changes to unitprice or quantity, the linetotal should update for that line and the totalprice label should sum the linetotal column.

I can't seem to find the correct event to use to calculate the totalprice label. I've tried cellvaluechanged, currentcelldirtystatechanged, rowleave. None of them seems to work right. I guess I need an event that fires after all the linetotal columns are calculated.

My pseudocode:

dt = getallitems(itemnumber);
dt.Columns.Add("LineTotal", typeof(double));
dt.Columns["Linetotal"].Expression = "[unitprice] * [quantity]";

dgv.DataSource = dt;

private void dgv_WhatEventToUse???(object sender, DataGridViewCellEventArgs e)
{
    //method to iterate the rows of the datagridview, and sum linetotal column
}

There must be some event that fires when the value of the calculated column is changed.

3条回答
该账号已被封号
2楼-- · 2020-03-24 04:57

It seems that your problem comes from the fact that your calculated column is part of the DataTable and not part of the DataGridView. I'm not sure if the DataGridView exposes an event for whenever the dgv's underlying data source changes. There is DataGridView.DataSourceChanged event, but that only seems to fire when you actually set the DataSource property, not when the DataTable changes itself with your calculations.

If you want to make it work without changing the structure of your code, subscribe to the DataTable's RowChanged event and you can scan the dgv and update your label from there. It's not exactly a clean solution, but it works. I would consider switching to a calculated column in the DataGridView if that's an option.

查看更多
爷、活的狠高调
3楼-- · 2020-03-24 05:01

Every time you need to refresh the calculated data column, just use again the assignement of expresion. It works for me.

dt.Columns["Linetotal"].Expression = "[unitprice] * [quantity]"

verbi gratia in my code

private void malla18_Mask_Validated(object sender, EventArgs e)
{
  analisis_Tabla_Lote.Columns["SUMA_MALLAS"].Expression = "100 - (Malla12 + Malla14 + Malla15 + Malla16 + Malla17 + Malla18 )";
  analisis_BindingSource.ResetBindings(false);
}

That's all you need!

查看更多
老娘就宠你
4楼-- · 2020-03-24 05:09

Normally I test out my answers before I give them, but I'm operating away from my dev PC, so I'm not 100% sure which route is best, but here are some ideas to try out.

On a DataGridView, you can use the CellEndEdit event to tell when a cell has been edited. there's also a CellLeave event, but I haven't used it and yo may need to experiment with it.

On a DataGrid, you can use the CurrentCellChanged event.

However, to do any calculations, you will need to extract your values fron the underlying Dataable or DataView (depending on what the control is bound to). I'v also found that using the DataGrid.CurrentCellChanged event is buggy and it's throwwn when the DataGrid is databaound, not just when a user edits the contents, so you may need to contend with that... I would imagine that the DataGridView's CellLeave event might have similar issues. Like I said, I'm not 100% sure, so you'll need to experiment.

Also, as Kyle suggested, you could try to use events from the underlying DataSource.

DataTable.RowChanged or DataView.ListChanged events wouldbe where I would start.

As I said, I am unable to test these myself, but hopefully one of these ideas will point you in the right direction.

查看更多
登录 后发表回答