Click here to Skip to main content
15,888,401 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Instead of rowwise change/commit to database using EntityFramework in WPF MVVM, I want to commit my changes cell wise.

Meanwhile, I also want to update the values in other cells based on the value entered in a particular cell. For instance, if user enters Certain amount in a column named "Amount", based on the value of "Amount", some other column also has to be updated. If the value of "Amount" is positive another column named "Debit" will have the same value as "Amount" and column named "Credit" will be 0. Similarly, vice-versa for the case where "Amount" is negative.

What I have tried:

In the View, inside a datagrid (which is bound to CollectionView defined in viewmodel of the view ) I have a template column Amount. Based on the value of this column, values in DatagridTextColumns, debit and credit should be updated.


C#
<DataGridTemplateColumn x:Name="Amount" Header="Amount">

    <DataGridTemplateColumn.CellTemplate>
         <DataTemplate>

            <TextBlock  Text="{Binding Amount}"/>   
             
          </DataTemplate>
     </DataGridTemplateColumn.CellTemplate>

      <DataGridTemplateColumn.CellEditingTemplate>

           <DataTemplate>
               <TextBox Text="{Binding Amount,Mode=TwoWay,UpdateSourceTrigger=LostFocus}" BorderThickness="0">
                   <interactivity:Interaction.Triggers>
                   	<interactivity:EventTrigger EventName="LostFocus">
                   		<interactivity:InvokeCommandAction Command="{Binding DataContext.SaveButtonClick,UpdateSourceTrigger=PropertyChanged,RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}" />
                   	</interactivity:EventTrigger>
                   </interactivity:Interaction.Triggers>   
                </TextBox>
            </DataTemplate>

       </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>                  

<DataGridTextColumn x:Name="DebitAmount" Header="Dr Amount" Binding="{Binding DebitAmount,UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn x:Name="CreditAmount" Header="Cr Amount" Binding="{Binding CreditAmount,UpdateSourceTrigger=PropertyChanged}"/>



In the ViewModel,

private ActionCommand SaveButtonCommand;
        public ICommand SaveButtonClick
        {
            get
            {
                return SaveButtonCommand;
            }
        }
 public void Save()
        {      
            
            RelationDBContext.SaveChanges();

            JournalCollectionView = CollectionViewSource.GetDefaultView(RelationDBContext.JournalLines.ToList());  //refreshing viewsource

            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(nameof(JournalCollectionView)));
            }

        }


In the Model,

<pre>   public decimal Amount
        {
            get { return _Amount; }
            set
            {
                _Amount = value;
                if (Amount >= 0)

                {
                    DebitAmount = value;
                    CreditAmount = 0;
                }
                else
                {
                    CreditAmount = value;
                    DebitAmount = 0;
                }
                
            }
        }



After doing this I was able to achieve both of my requirements. But I faced a problem. As I need the changes made on a particular cell (which is commited to database, which in turn also updates two other cells Debit and Credit) to immediately reflect on the datagrid, I raised the propertychangedevent for the CollectionView (JournalCollectionView) that is bound to my datagrid. With this, the focus of the cursor does not stay on the row that the user is working on, Instead the whole datagrid gets refreshed and the focus is lost from the row that the user is working on.

I would appreciate any form of help or suggestion.
Posted
Updated 24-Jan-19 0:43am

1 solution

So before you refresh the grid, get/retain the current cursor position, and restore that position after the refresh.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900