How to update the value of one cell based on another in WPF Grid View

Asked

Viewed 379 times

3

I have the following Grid, I would like to know how I can do so that when I leave the Gain or Spend field it updates the Total?

If there’s any other way I’m happy to meet.

Total = (Gain - Expense)

    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            
    }     

File . xaml

   <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>

1 answer

1

The best way to do this is through a ViewModel. That Viewmodel should implement the interface INotifyPropertyChanged. The UpdateSourceTrigger of the Binding of the properties ValorGanho and ValorGasto needs to be LostFocus, that when you lose focus, set will be executed. Then whenever a set in ValorPago or ValorGanho, 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 below, and you remove the event LostFocus

<DataTemplate>
    <TextBox Name="txtGanho" Text="{Binding Ganho, Mode = TwoWay, UpdateSourceTrigger = LostFocus}" />
</DataTemplate>

It is not a good practice in WPF to work with events since it can work with MVVM. And recovering objects from another grid cell in WPF can be quite laborious. So I leave this approach.

https://msdn.microsoft.com/pt-br/library/system.componentmodel.inotifypropertychanged(v=vs.110). aspx

  • Thanks for your reply @Murilo as soon as I get I will try to implement this way. I didn’t know there was such a MVVM, do you know any material for me to learn? Because I program everything with events.

  • I don’t have specific material. I learned from forums and tutorials (via google itself); but you may be able to retrieve your textbox through Treevisual https://msdn.microsoft.com/pt-br/library/system.windows.media.visualtreehelper(v=vs.110). aspx http://www.wpftutorial.net/logicalandvisualtree.html

Browser other questions tagged

You are not signed in. Login or sign up in order to post.