diff --git a/src/ReactiveUI.Maui/RoutedViewHost.cs b/src/ReactiveUI.Maui/RoutedViewHost.cs
index 7ee116a3ab..93bc2e9877 100644
--- a/src/ReactiveUI.Maui/RoutedViewHost.cs
+++ b/src/ReactiveUI.Maui/RoutedViewHost.cs
@@ -4,6 +4,7 @@
// See the LICENSE file in the project root for full license information.
using System;
+using System.Collections.Specialized;
using System.Reactive;
using System.Reactive.Concurrency;
using System.Reactive.Disposables;
@@ -40,6 +41,8 @@ public class RoutedViewHost : NavigationPage, IActivatableView, IEnableLogger
typeof(RoutedViewHost),
false);
+ private string? _action;
+
///
/// Initializes a new instance of the class.
///
@@ -50,6 +53,13 @@ public RoutedViewHost()
{
var currentlyNavigating = false;
+ Observable.FromEventPattern(
+ x => Router!.NavigationStack.CollectionChanged += x,
+ x => Router!.NavigationStack.CollectionChanged -= x)
+ .Where(_ => !currentlyNavigating && Router?.NavigationStack.Count == 0)
+ .Subscribe(async _ => await SyncNavigationStacksAsync())
+ .DisposeWith(disposable);
+
Router?
.NavigateBack
.Subscribe(async _ =>
@@ -64,6 +74,7 @@ public RoutedViewHost()
currentlyNavigating = false;
}
+ _action = "NavigatedBack";
InvalidateCurrentViewModel();
await SyncNavigationStacksAsync();
})
@@ -108,8 +119,7 @@ public RoutedViewHost()
x => Popped += x,
x => Popped -= x);
- // NB: Catch when the user hit back as opposed to the application
- // requesting Back via NavigateBack
+ // NB: User pressed the Application back as opposed to requesting Back via Router.NavigateBack.
poppingEvent
.Where(_ => !currentlyNavigating && Router is not null)
.Subscribe(_ =>
@@ -119,6 +129,7 @@ public RoutedViewHost()
Router.NavigationStack.RemoveAt(Router.NavigationStack.Count - 1);
}
+ _action = "Popped";
InvalidateCurrentViewModel();
})
.DisposeWith(disposable);
@@ -132,8 +143,6 @@ public RoutedViewHost()
x => PoppedToRoot += x,
x => PoppedToRoot -= x);
- // NB: Catch when the user hit back as opposed to the application
- // requesting Back via NavigateBack
poppingToRootEvent
.Where(_ => !currentlyNavigating && Router is not null)
.Subscribe(_ =>
@@ -146,6 +155,7 @@ public RoutedViewHost()
}
}
+ _action = "PoppedToRoot";
InvalidateCurrentViewModel();
})
.DisposeWith(disposable);
@@ -183,7 +193,7 @@ protected virtual IObservable PagesForViewModel(IRoutableViewModel? vm)
{
if (vm is null)
{
- return Observable.Empty;
+ return Observable.Empty();
}
var ret = ViewLocator.Current.ResolveView(vm);
@@ -245,8 +255,15 @@ protected void InvalidateCurrentViewModel()
var vm = Router?.GetCurrentViewModel();
if (CurrentPage is IViewFor page && vm is not null)
{
- // don't replace view model if vm is null
- page.ViewModel = vm;
+ if (page.ViewModel?.GetType() == vm.GetType())
+ {
+ // don't replace view model if vm is null or an incompatible type.
+ page.ViewModel = vm;
+ }
+ else
+ {
+ this.Log().Info($"The view type '{page.GetType().FullName}' is not compatible with '{vm.GetType().FullName}' this was called by {_action}, the viewmodel was not invalidated");
+ }
}
}
diff --git a/version.json b/version.json
index 3e63a0b843..012f6e6ef4 100644
--- a/version.json
+++ b/version.json
@@ -1,6 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
- "version": "19.3",
+ "version": "19.4",
"publicReleaseRefSpec": [
"^refs/heads/master$", // we release out of master
"^refs/heads/main$",