Sunday, March 6, 2011

Two 'self-updating' properties in WPF MVVM

Considering you have an MVVM Architecture in WPF like Josh Smith's examples

How would you implement two properties 'synced' that update eachother? I have a Price property, and a PriceVatInclusive property in my model.

-When the Price changes, I want to see the Vat inclusive price to automatically be 'Price * 1.21'.

-Vice versa, when the PriceVatInclusive changes, I want the Price to be 'PriceVatInclusive / 1.21'

Any ideas on that?

And what if your model is a Entity framework entiry? You can't use the approach above then... no? Should you put calculating code in the ViewMOdel or ... ?

From stackoverflow
  • One way:

        public class Sample : INotifyPropertyChanged
        {
            private const double Multiplier = 1.21;
            #region Fields
            private double price;
            private double vat;
            #endregion
    
            #region Properties
            public double Price
            {
                get { return price; }
                set
                {
                    if (price == value) return;
                    price = value;
                    OnPropertyChanged(new PropertyChangedEventArgs("Price"));
                    Vat = Price * Multiplier;
                }
            }
    
            public double Vat
            {
                get { return vat; }
                set
                {
                    if (vat == value) return;
                    vat = value;
                    OnPropertyChanged(new PropertyChangedEventArgs("Vat"));
                    Price = Vat / Multiplier;
                }
            }
            #endregion
    
            #region INotifyPropertyChanged Members
            protected void OnPropertyChanged(PropertyChangedEventArgs e)
            {
                PropertyChangedEventHandler ev = PropertyChanged;
                if (ev != null)
                {
                    ev(this, e);
                }
            }
            public event PropertyChangedEventHandler PropertyChanged;
    
            #endregion
        }
    

    If you can derive from DependencyObject, you can use Dependency Properties.

    public class Sample : DependencyObject
    {
        private const double Multiplier = 1.21;
    
        public static readonly DependencyProperty VatProperty =
            DependencyProperty.Register("Vat", typeof(double), typeof(Sample), 
            new PropertyMetadata(VatPropertyChanged));
    
        public static readonly DependencyProperty PriceProperty =
            DependencyProperty.Register("Price", typeof(double), typeof(Sample), 
            new PropertyMetadata(PricePropertyChanged));
    
        private static void VatPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            Sample sample = obj as Sample;
            sample.Price = sample.Vat / Multiplier;
        }
    
        private static void PricePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            Sample sample = obj as Sample;
            sample.Vat = sample.Price * Multiplier;
        }
    
        #region Properties
        public double Price
        {
            get { return (double)GetValue(PriceProperty); }
            set { SetValue(PriceProperty, value); }
        }
    
        public double Vat
        {
            get { return (double)GetValue(VatProperty); }
            set { SetValue(VatProperty, value); }
        }
        #endregion
    }
    
    Tom Deleu : Yes ok, But what if your model is a Entity framework entiry? You can't use the approach above then... no? Should you put calculating code in the ViewMOdel or ... ?

0 comments:

Post a Comment