Question:
I have the following Grid, I would like to know how I can make it so that when I leave the Gain or Spend field it updates the Total?
If there is another way to do it, I'm happy to know.
Total = (Gain – Spend)
private void txtGanho_LostFocus(object sender, RoutedEventArgs e)
{
TextBox txtGanho = (TextBox)sender;
//Aqui eu tenho o valor do Ganho, como posso encontrar na Grid os TextBox com Gasto e Total
}
private void txtGasto_LostFocus(object sender, RoutedEventArgs e)
{
TextBox txtGasto = (TextBox)sender;
//Aqui tenho o valor do Gasto, como posso encontrar na Grid os TextBox com Ganho e Total
}
.xaml file
<DataGrid x:Name="dgControleFinanceiro" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Id" Binding="{Binding Id}" IsReadOnly="True" />
<DataGridTextColumn Header="Data" Binding="{Binding Data}" IsReadOnly="True"/>
<DataGridTemplateColumn Header="Ganho do dia" IsReadOnly="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Name="txtGanho" Text="{Binding Ganho}" LostFocus="txtGanho_LostFocus"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Gasto do dia" IsReadOnly="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Name="txtGasto" Text="{Binding Gasto}" LostFocus="txtGasto_LostFocus"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Total do dia" IsReadOnly="true">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Name="txtTotal" Text="{Binding Total}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Answer:
The best way to do this is through a ViewModel
. This ViewModel must implement the INotifyPropertyChanged
interface. The UpdateSourceTrigger
of the Binding of ValorGanho
and ValorGasto
properties must be LostFocus
, when it loses focus, the set
will be executed. So whenever you happen one set
in ValorPago
or ValorGanho
, the View will be notified of the change in Total
, reflecting on the grid.
public class ControleFinanceiroViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
protected void NotificarMudancaPropriedade([CallerMemberName] string nomePropriedade = null)
{
if (nomePropriedade != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(nomePropriedade));
}
}
private decimal valorGasto;
public decimal ValorGasto
{
get { return this.valorGasto; }
set
{
this.valorGasto = value;
this.NotificarMudancaPropriedade();
this.NotificarMudancaPropridade("Total");
}
}
private decimal valorGanho;
public decimal ValorGanho
{
get { return this.valorGanho; }
set
{
this.valorGanho= value;
this.NotificarMudancaPropriedade();
this.NotificarMudancaPropridade("Total");
}
}
public decimal Total
{
get { return this.ValorGanho - this.ValorGasto; }
}
}
Binding will look like this, and you remove the LostFocus
event
<DataTemplate>
<TextBox Name="txtGanho" Text="{Binding Ganho, Mode = TwoWay, UpdateSourceTrigger = LostFocus}" />
</DataTemplate>
It is not a good practice in WPF to work with events, as it can work with MVVM. And retrieving objects from another grid cell in WPF can be quite cumbersome. So I leave this approach.
https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx