Hello guys,
Can't find a solution on the below issue.
I have a datagrid in WPF. When the user changes manually the values of the columns "Units" and "Unit Price" I want an automatic calculation for the column "Amount". But no matter what I do when I change Units
for example and then I change cell with "TAB" or with the mouse click, I don't see any changes because the current "Units" cell still has the previous value. But if I press enter and with the appropriate code of course, it works the
amount changes. I want when I press Enter, or Tab or left mouse click on another cell to have a successful "Amount" calculation on all three scenarios.
Below a screenshot of the datagrid and the code I tried so far.
The datagrid's source is a DataTable... purchasesDatagrid.ItemsSource = DataTablePurchases.DefaultView;
private async void purchasesDatagrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) { try { await Task.Delay(100); int i = 0; foreach (DataRowView row in purchasesDatagrid.ItemsSource) { string Units_ = row["Units"] == null ? "0" : row["Units"].ToString(); string UnitPrice_ = row["UnitPrice"] == null ? "0" : row["UnitPrice"].ToString(); double Units = Regex.IsMatch(Units_, @"^[0-9.]+$") ? double.Parse(Units_) : 0; double UnitPrice = Regex.IsMatch(UnitPrice_, @"^[0-9.]+$") ? double.Parse(UnitPrice_) : 0; row["Amount"] = Units * UnitPrice; } DataTablePurchases.AcceptChanges(); purchasesDatagrid.UpdateLayout(); /* THIS IS ANOTHER APPROACH I TRIED: the cell and index are from a custom class that I use DataGridCell cell = GlobalEvents.DataGridHelper.GetCell(purchasesDatagrid.SelectedCells[0]); var index = GlobalEvents.DataGridHelper.GetRowIndex(cell); DataGridRow row = purchasesDatagrid.ItemContainerGenerator.ContainerFromIndex(index) as DataGridRow; //here we get the actual row at selected index DataRowView drvPurchases = (DataRowView)purchasesDatagrid.ItemContainerGenerator.ItemFromContainer(row); //here we get the actual data item behind the selected row string Units_ = drvPurchases["Units"] == null ? "0" : drvPurchases["Units"].ToString(); double Units = Regex.IsMatch(Units_, @"^[0-9.]+$") ? double.Parse(Units_) : 0.00; string UnitPrice_ = drvPurchases["UnitPrice"] == null ? "0" : drvPurchases["UnitPrice"].ToString(); double UnitPrice = Regex.IsMatch(UnitPrice_, @"^[0-9.]+$") ? double.Parse(UnitPrice_) : 0.00; drvPurchases["Amount"] = Units * UnitPrice; DataTablePurchases.Rows[index]["Amount"] = Units * UnitPrice; */ } catch (Exception ex) { } }
Note that without async and the await Task it doesn't work at all.
I also tried events like below, but with no luck.
private void purchasesDatagrid_KeyDown(object sender, System.Windows.Input.KeyEventArgs e) { if (e.Key.ToString() == "Return" || e.Key.ToString() == "Tab") { /* WITH THE SAME CODE LIKE IN FUNCTION ABOVE */ } } private void purchasesDatagrid_CurrentCellChanged(object sender, EventArgs e) { if (e.Key.ToString() == "Return" || e.Key.ToString() == "Tab") { /* WITH THE SAME CODE LIKE IN FUNCTION ABOVE */ } }