user5552042
user5552042

Reputation: 33

Wpf - How to control observable collection updates

In the parent there is a Observable Collection PendingPayment that has a list of all pending payments of sales with a column amount paid.

Then the user can select a particular sale and open it in new child window.

The thing thats going wrong is if the user just edits the text box paid amount in child window and closes the window without saving the new paid amount to database,the observable collection containing Amount paid column in the parent window gets updated.

What I want is it the collection to get updated only when the values are updated in the database.

Upvotes: 0

Views: 551

Answers (2)

E-Bat
E-Bat

Reputation: 4892

Whenever possible (I've never see a reason why it cannot),for listing purpose use proxy or flatted objects, you can implement this using projections query. Then user select an item from a list and the only thing you need to grab is a key to load the full object with its required object graph as the use case might dictate.

Here is a sample implementation using Entity Framework and c# lambda expressions:

Using anonymous object:

var anonymousListProjection = DbContext.PendingPayments.Select( pp=> 
    new { pp.Order, pp.Amount})         


Using a hardcoded proxy:

var hardcodedListProjection = DbContext.PendingPayments.Select( pp=> 
    new PendingPaymentProxy { Order = pp.Order, Amount = pp.Amount}) 

//To return an observable:    
var observableColl = new ObservableCollection<PendingPaymentProxy>
    (hardcodedListProjection.Tolist());

public class PendingPaymentProxy 
{
   public string Order { get; set; }
   public decimal Amount{ get; set; }    
}

Apart from avoiding possibles performance problems due to unintentional loading real objects, this way you only have to worry for your list when the user do save in the detail view.

Upvotes: 1

aegar
aegar

Reputation: 764

This can be achieved by creating a copy of your sale object when the user select it in the list, and then using this copy as the view model of your child view.

You will then be able to set the new values in the original object from your list only once the save button has been clicked and the database update succeed.

An other way to proceed if you need to edit only few of the object properties would be to create and editor object and use it as the child window's view model. Something like this :

public class Sale
{
    public int PaidAmount { get; set; }
    public int Some { get; set; }
    public int More { get; set; }
    public int Properties { get; set; }
}

public class SaleEditor
{
    private Sale _sale;

    public int PaidAmount { get; set; }

    public SaleEditor(Sale sale)
    {
        _sale = sale;
        PaidAmount = sale.PaidAmount;
    }

    public void Save()
    {
        // update your data here
        _sale.PaidAmount = PaidAmount;
    }
}

If you need your original object to update the database, then the save method could first update the object and the revert the changes if DB update failed :

    public void Save()
    {
        var oldAmount = _sale.PaidAmount;
        _sale.PaidAmount = PaidAmount;

        if (!SalesDB.Update(_sale))
            _sale.PaidAmount = oldAmount;
            // you could also read back the value from DB
    }

Upvotes: 1

Related Questions