You are correct, using the WhenAny / ObservableForProperty method incorrectly can lead to a memory leak in your application if you are not careful. Consider the following code:
public ItemInAListBoxViewModel(MainWindowViewModel mainWindow) { this.window = mainWindow; // Reset the "selected" when the user minimizes this.WhenAnyValue(x => x.window.IsMinimized) .Where(x => x == true) .Subscribe(x => this.IsSelected = false); }
Since we have WhenAny'd through an object whose life time is longer than ours (i.e. the ListBox vs Window element), we keep the ListBox elements forever until the window disappears (which may never be in your application).
You will avoid the vast majority of these cases, if only your character should be only when on your own object (i.e. always this.WhenAny , never someObject.WhenAny ).
Special Note on Dependency Properties
No matter what you have , to get rid of any WhenAny that passes through DependencyProperty, otherwise you will miss. Because Windows.
Crap, what should I do now?
A new feature has been added to ReactiveUI to handle the script in which you want to do this, but called "Activation". You can find additional information at:
Now we can define the area of βββthings that should be active only when the screen is onβ that will disappear immediately after the View and its ViewModel are removed from the screen (i.e. removed from the visual tree in WPF).
public ItemInAListBoxViewModel(MainWindowViewModel mainWindow) { this.window = mainWindow; Activator = new ViewModelActivator(); // This gets called every time the View for this VM gets put on screen this.WhenActivated(d => { // The 'd' is for "Dispose this when you're Deactivated" d(this.WhenAnyValue(x => x.window.IsMinimized) .Where(x => x == true) .Subscribe(x => this.IsSelected = false)); }); }
For this to work, here is what must be true:
- Your VieWModel should implement
ISupportsActivation (super easy) - The view associated with your ViewModel should also call
WhenActivated .
That sounds super complicated!
It looks like this, but it is not at all. Just remember two things:
- Do not WhenAny through objects that stick out forever, unless you also stick forever
- If you need to use WhenActivated.
Paul betts
source share