I have a requirement in WPF
, I made a ViewModel
call AssignFacturasVM for my View, in which I have a Label
that is linked to a property float
called AccumulatedAmount of my ViewModel
and I also have a Datagrid
whose ItemSource
is a property of my ViewModel
that is a ObservableCollection
call CuentasxCobrar that among its properties contains a float
call Import (which I edit inside the Datagrid
with a TextBox
) and a bool
call Selected (which I edit inside the DataGrid
with a CheckBox
).
What I need to do is that every time the user Checks some CheckBox
, the AccumulatedAmount property is updated , adding all the Amounts of the rows DataGrid
that have Selected in true
.
I hope I have explained myself.
For this, I have a Function inside me ViewModel
that is in charge of accumulating these amounts depending on if it is Selected in true, but I have not been able to find how and when to launch this function, the data in my collection and in me ViewModel
are updated correctly depending on of what the user modifies in the View
, I only need to make the calculation of the Accumulated Amount be carried out correctly ...
Inside my ViewModel cs:
private ObservableCollection<CuentasxCobrarCL> _cuentasxcobrar;
public ObservableCollection<CuentasxCobrarCL> CuentasxCobrar
{
set
{
_cuentasxcobrar = value;
ActualizaImporteAcumulado();
OnPropertyChanged("CuentasxCobrar");
OnPropertyChanged("ImporteAcumulado");
}
get { return _cuentasxcobrar; }
}
private void ActualizaImporteAcumulado()
{
_importeacumulado = 0;
foreach (var item in _cuentasxcobrar)
{
_importeacumulado += item.seleccionada ? item.importepago : 0;
}
OnPropertyChanged("ImporteAcumulado");
}
In my XAML:
<sdk:DataGridTemplateColumn Header="Seleccionar" Width="95" CanUserSort="False" >
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Name="chkseleccionada"
IsChecked="{Binding seleccionada, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
NotifyOnValidationError=True,
ValidatesOnExceptions=True,
ValidatesOnNotifyDataErrors=True,
ValidatesOnDataErrors=True}"
HorizontalAlignment="Center" />
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
<sdk:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding seleccionada, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
NotifyOnValidationError=True,
ValidatesOnExceptions=True,
ValidatesOnNotifyDataErrors=True,
ValidatesOnDataErrors=True}" />
</DataTemplate>
</sdk:DataGridTemplateColumn.CellEditingTemplate>
Part of my CuentasxCobrarCL.cs:
public class CuentasxCobrarCL : INotifyPropertyChanged
{
public int idcli { get; set; }
public DateTime fecha { get; set; }
public DateTime fechadepago { get; set; }
#region public float importepago
private float _importepago;
public float importepago
{
get
{ return _importepago; }
set
{
_importepago = value;
_saldonuevo = _adeudo - _importepago;
OnPropertyChanged("saldonuevo");
OnPropertyChanged("importepago");
}
}
#endregion
#region public bool seleccionada
private bool _seleccionada;
public bool seleccionada
{
get
{ return _seleccionada; }
set
{
_seleccionada = value;
OnPropertyChanged("seleccionada");
}
}
#endregion
#region PropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
Any suggestion?
You have to make a couple of changes to make it work. The main thing is to know that observable collection does not fire the on change method when some value of the objects it contains changes, but it only fires when the observablecollection itself changes.
We must have a way to know when the child class is updated, and tell the parent, who has the observableCollection, that it has to update the value of the check.
The problem? there is no simple way to do this. We have to build an event for each time the child class changes, and this is a problem, because we have to have an event for each child.
In your case, we will do something else.
We need to add to your VM a property that knows what item is selected in the grid, and when another item is selected in the grid, recalculate the total.
Add the following to your grid:
Then to your vm add the following:
With this, every time you change rows, the value of your total should be updated.
You can declare the list as an object itself and put the total as a property of the list:
Then in the ViewModel in the propertyChanged event it will update that value automatically because it will be inside the list
I don't pretend to be the answer, but I think it can help you if you know how to apply it.