WhenActivated is called twice when used in Views and ViewModels hosted in ViewModelViewHost control

The WhenActivated call used in SubView returns an IDisposable object, which can be used within the same call to WhenActivated. This will remove your subscription from activation events upon deactivation. Doing so prevents the secondary activation and disposal from occurring.

In the SubView constructor, change this:

this.WhenActivated(d =>
{
    Debug.WriteLine("SubView activated.");
    d(Disposable.Create(() => { Debug.WriteLine("SubView deactivated."); }));

    d(this // ViewModel -> DataContext
        .WhenAnyValue(v => v.ViewModel)
        .BindTo(this, v => v.DataContext));
});

to this:

System.IDisposable whenActivatedSubscription = null;
whenActivatedSubscription = this.WhenActivated(d =>
{
    Debug.WriteLine("SubView activated.");
    d(Disposable.Create(() => { Debug.WriteLine("SubView deactivated."); }));

    d(this // ViewModel -> DataContext
        .WhenAnyValue(v => v.ViewModel)
        .BindTo(this, v => v.DataContext));
    d(whenActivatedSubscription); // <- Dispose of the activation subscription here
});

The reason why this solution works is because since your view is being destroyed, the activation itself needs to be disposed of as a part of this process as well.