Home > Software engineering >  How to force update on a read only property?
How to force update on a read only property?

Time:04-14

I am trying to automatically calculate a total value on my object. Let's say my object is:

public class Sale
{
    public double Amount { get; set; }
    public double Price { get; set; }
    public double Total { get { return Amount * Price; } }
}

I have two Entry on my page so the user can type the Amount and the Price values, and a Label to show the Total value:

<Entry Placeholder="Amount"
       ReturnType="Done"
       Keyboard="Numeric"
       Text="{Binding MySale.Amount, Mode=OneWayToSource, StringFormat='{}{0:N0}'}"/>

<Entry Placeholder="Price"
       ReturnType="Done"
       Keyboard="Numeric"
       Text="{Binding MySale.Price, Mode=OneWayToSource, StringFormat='{}{0:N0}'}"/>

<Label Text="{Binding MySale.Total, StringFormat='{}R$ {0:N2}'}"/>

The BindingContext is correctly defined as my view model, and the MySale object implements INotifyPropertyChanged:

private Sale _mySale;
public Sale MySale
{
    get { return _mySale; }
    set { SetProperty(ref _mySale, value); } // The SetProperty is defined in my BaseViewModel
}

The problem is that when I change the value of the entries, the value of the label is not updated. I even tried to manually assign the Amount and the Price values to the entries texts when the controls are unfocused, but it also didn't work.

I'm not sure if it changes anything, but my application is a MVVM Xamarin.Forms app.

-- EDIT -- This is my BaseViewModel class:

public class BaseViewModel : INotifyPropertyChanged
{
    string title = string.Empty;
    public string Title
    {
        get { return title; }
        set { SetProperty(ref title, value); }
    }

    bool isBusy = false;
    public bool IsBusy
    {
        get { return isBusy; }
        set { SetProperty(ref isBusy, value); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = "")
    {
        if (EqualityComparer<T>.Default.Equals(storage, value))
            return false;
        storage = value;
        this.OnPropertyChanged(propertyName);
        return true;
    }
}

CodePudding user response:

when you set the value of Amount or Price you can raise mulitple PropertyChanged events

public class Sale : BaseViewModel
{
    private double amount;
    private double price;

    public double Amount
        get { return amount; }
        set { SetProperty(ref amount, value);
              this.OnPropertyChanged("Total"); }

    public double Price
        get { return price; }
        set { SetProperty(ref price, value); 
              this.OnPropertyChanged("Total"); } 

    public double Total { get { return Amount * Price; } }
}
  • Related