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$",