d0neall
d0neall

Reputation: 81

How to notify Properties outside of an Object instance?

I am a WPF beginner and I have an issue with the PropertyChanged Events:

I have a viewmodel that contains an instance of another viewmodel. (I will use general names here)

I want the instance of the AxisVM to notify my SomeDouble property. (Can´t use a converter)

edit: I didn´t include the full classes here, the PropertyChangedEvent is obviously implemented.

public class ViewModel : INotifyPropertyChanged
{
   private AxisVM axis;
 
   public ViewModel()
   {
      this.AxisVM = new AxisVM();
   }
   
   public AxisVM Axis
   {
     get { return axis}; 
     set { axis = value; FireOnPropertyChanged(); }
   }

   public double SomeDouble
   {
     get { return axis.Lowerlimit * 1.5 }; 
   }

}

AxisVM also inherits from INotifyPropertyChanged (I use the ClassMemberName)

public class AxisVM: INotifyPropertyChanged
{
   private double lowerLimit;

   public double LowerLimit
   {
     get { return lowerLimit }; 
     set { lowerLimit = value; FireOnPropertyChanged(); }
   }

}

In XAML I bind the Viewmodel as a DataContext (where doesn´t matter in this case I think) and then bind the Lower limit to a textbox.

When I edit the textbox, the event of the lower limit of the axis gets fired and the value is changed (view and viewmodel) but I need to notify my SomeDouble property because it gets updated when the lower limit changes.

The property changed event of the axis instance in my ViewModel never gets fired even though I access a property of it (which does fire its event but doesn´t notify my SomeDouble property).

I am at loss right now, any help is appreciated.

Upvotes: 2

Views: 1304

Answers (3)

mm8
mm8

Reputation: 169200

Just handle the PropertyChanged of the AxisVM in your view model:

public class ViewModel : INotifyPropertyChanged
{
    private readonly AxisVM axis;

    public ViewModel()
    {
        axis = new AxisVM();
        axis.PropertyChanged += Axis_PropertyChanged;      
    }

    private void Axis_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        FireOnPropertyChanged(nameof(SomeDouble));
    }

    ...
}

Upvotes: 4

Mighty Badaboom
Mighty Badaboom

Reputation: 6155

You could use an event for this.

Add an event in your AxisVM

public class AxisVM: INotifyPropertyChanged
{
   public event EventHandler LowerLimitChanged;  

   private double lowerLimit;

   public double LowerLimit
   {
     get { return lowerLimit }; 
     set { lowerLimit = value; FireOnPropertyChanged(); LowerLimitChanged?.Invoke(this, EventArgs.Empty); }
   }
}

And subscribe like this

public class ViewModel : INotifyPropertyChanged
{
   private AxisVM axis;

   public ViewModel()
   {
      this.AxisVM = new AxisVM();
      this.AxisVM.LowerLimitChanged += OnLowerLimitChanged;
   }

   public AxisVM Axis
   {
     get { return axis}; 
     set { axis = value; FireOnPropertyChanged(); }
   }

   public double SomeDouble
   {
     get { return axis.Lowerlimit * 1.5 }; 
   }

   public void OnLowerLimitChanged(object sender, EventArgs e)
   {
      FireOnPropertyChanged("SomeDouble");
   }
}

You can remove FireOnPropertyChanged("SomeDouble"); in your property public AxisVM Axis because this will only be fired when the instance of AxisVM is set and not when a property in this instance has changed.

Upvotes: 1

Jonatan Dragon
Jonatan Dragon

Reputation: 5017

When you implemented INotifyPropertyChanged in AxisVM, you added PropertyChanged event there. Handle it in ViewModel and fire FireOnPropertyChanged().

Axis.PropertyChanged += OnAxisVMPropertyChanged(...)
void OnAxisVMPropertyChanged(..)
{
    // Check property name
    // Fire OnPropertyChanged for LowerLimit
}

Upvotes: 0

Related Questions