In my current project I've faced the following situation:
At the beginning I thought about hooking to VM2.PropertyChanged event to check for the property I want and change the VM3 affected property accordingly, as:
public class VM1 : INotifyPropertyChanged
{
public property VM2 VM2 { get; private set; }
public property VM3 VM3 { get; private set; }
public VM1()
{
this.VM2 = new VM2();
this.VM3 = new VM3();
this.VM2.PropertyChanged += this.VM2_PropertyChanged;
}
private void VM2_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
// if e.PropertyName equals bla then VM3.SomeProperty = lol.
}
}
This means that, since I can not unhook the event in this class, I have a memory leak.
So I end up passing an Action to VM2 so that it will be called when its important property changes the value, as:
public class VM2 : INotifyPropertyChanged
{
public Action WhenP1Changes { get; set; }
private bool _p1;
public bool P1
{
get
{
return _p1;
}
set
{
_p1 = value;
this.WhenP1Changes();
this.PropertyChanged(this, new PropertChangedEventArgs("P1");
}
}
}
public class VM1 : INotifyPropertyChanged
{
public VM2 VM2 { get; private set; }
public VM3 VM3 { get; private set; }
public VM1()
{
this.VM2 = new VM2();
this.VM3 = new VM3();
this.VM2.WhenP1Changes = () => VM3.SomeProperty = "lol";
}
}
Do I have a memory leak here?
PD: It would be great if you can also answer to: - Is this even a good practice?
Thanks
Do I have a memory leak here?
The lambda assigned to VM2.WhenP1Changes
captures this
VM1 instance (needed to access the VM3
property), so as long as the view model VM2
is alive, it will keep VM1
alive. Whether this ends up being a leak depends on the lifecycle of those view models, but the implications are effectively the same as your first example using events.