diff --git a/src/Maui/Prism.Maui/Mvvm/ViewModelLocator.cs b/src/Maui/Prism.Maui/Mvvm/ViewModelLocator.cs
index 57cc71f72d..727e857f0d 100644
--- a/src/Maui/Prism.Maui/Mvvm/ViewModelLocator.cs
+++ b/src/Maui/Prism.Maui/Mvvm/ViewModelLocator.cs
@@ -1,4 +1,4 @@
-namespace Prism.Mvvm;
+namespace Prism.Mvvm;
///
/// This class defines the attached property and related change handler that calls the .
@@ -9,7 +9,15 @@ public static class ViewModelLocator
/// Instructs Prism whether or not to automatically create an instance of a ViewModel using a convention, and assign the associated View's to that instance.
///
public static readonly BindableProperty AutowireViewModelProperty =
- BindableProperty.CreateAttached("AutowireViewModel", typeof(ViewModelLocatorBehavior), typeof(ViewModelLocator), ViewModelLocatorBehavior.Automatic);
+ BindableProperty.CreateAttached("AutowireViewModel", typeof(ViewModelLocatorBehavior), typeof(ViewModelLocator), ViewModelLocatorBehavior.Automatic, propertyChanged: OnViewModelLocatorBehaviorChanged);
+
+ private static void OnViewModelLocatorBehaviorChanged(BindableObject bindable, object oldValue, object newValue)
+ {
+ if (newValue is ViewModelLocatorBehavior behavior && behavior == ViewModelLocatorBehavior.Forced)
+ {
+ Autowire(bindable);
+ }
+ }
internal static readonly BindableProperty ViewModelProperty =
BindableProperty.CreateAttached("ViewModelType",
diff --git a/src/Maui/Prism.Maui/Mvvm/ViewModelLocatorBehavior.cs b/src/Maui/Prism.Maui/Mvvm/ViewModelLocatorBehavior.cs
index 9e04a3ca78..0c9ea79b7f 100644
--- a/src/Maui/Prism.Maui/Mvvm/ViewModelLocatorBehavior.cs
+++ b/src/Maui/Prism.Maui/Mvvm/ViewModelLocatorBehavior.cs
@@ -1,7 +1,33 @@
namespace Prism.Mvvm;
+///
+/// Defines the behavior that the should use.
+///
public enum ViewModelLocatorBehavior
{
+ ///
+ /// The ViewModel will be lazily loaded by the Page/Region Navigation Services
+ /// or the DialogService.
+ ///
+ ///
+ /// This is the default and recommended value for the ViewModelLocator. This will
+ /// allow the View to be fully initialized and ensure that the proper ViewModel is
+ /// resolved based on the route name.
+ ///
Automatic,
- Disabled
+
+ ///
+ /// This will disable Prism's automatic ViewModel Location
+ ///
+ Disabled,
+
+ ///
+ /// This is not recommended for most situations
+ ///
+ ///
+ /// This is likely to cause breaks in the Container Scoping. It is recommended that
+ /// you allow Prism Page/Region Navigation Services or the Dialog Service properly
+ /// resolve the ViewModel.
+ ///
+ Forced
}
diff --git a/src/Maui/Prism.Maui/Navigation/Xaml/Navigation.cs b/src/Maui/Prism.Maui/Navigation/Xaml/Navigation.cs
index 4952349be1..d4b264b6ff 100644
--- a/src/Maui/Prism.Maui/Navigation/Xaml/Navigation.cs
+++ b/src/Maui/Prism.Maui/Navigation/Xaml/Navigation.cs
@@ -1,4 +1,4 @@
-using System.ComponentModel;
+using System.ComponentModel;
using Prism.Common;
using Prism.Navigation.Internals;
@@ -154,6 +154,15 @@ public static IContainerProvider GetContainerProvider(this BindableObject bindab
{
if (page.Parent is FlyoutPage flyout && flyout.Flyout == page)
return flyout.GetContainerProvider();
+
+ if (Mvvm.ViewModelLocator.GetAutowireViewModel(page) == Mvvm.ViewModelLocatorBehavior.Forced)
+ {
+ container = ContainerLocator.Container.CreateScope();
+ var accessor = container.Resolve();
+ accessor.Page = page;
+ SetContainerProvider(page, container);
+ return container;
+ }
}
else if (bindable is Element element && element.Parent is not null)
return GetContainerProvider(element.Parent);
diff --git a/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs b/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs
index 657ede505a..7ff873c66e 100644
--- a/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs
+++ b/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs
@@ -40,6 +40,23 @@ public void PagesInjectScopedInstanceOfIPageAccessor(string uri)
}
}
+ [Fact]
+ public async Task ViewModelLocator_Forced_SetsContainer_ResolvedViewModel()
+ {
+ var mauiApp = CreateBuilder(prism => prism
+ .RegisterTypes(c => c.RegisterForNavigation())
+ .CreateWindow("ForcedView"))
+ .Build();
+ var window = GetWindow(mauiApp);
+
+ Assert.IsType(window.Page);
+ Assert.IsType(window.Page.BindingContext);
+
+ var viewModel = (ForcedViewModel)window.Page.BindingContext;
+ Assert.NotNull(viewModel.Page);
+ Assert.IsType(viewModel.Page);
+ }
+
[Fact]
public async Task AddsPageFromRelativeURI()
{
diff --git a/tests/Maui/Prism.DryIoc.Maui.Tests/Mocks/ViewModels/ForcedViewModel.cs b/tests/Maui/Prism.DryIoc.Maui.Tests/Mocks/ViewModels/ForcedViewModel.cs
new file mode 100644
index 0000000000..7878eff78e
--- /dev/null
+++ b/tests/Maui/Prism.DryIoc.Maui.Tests/Mocks/ViewModels/ForcedViewModel.cs
@@ -0,0 +1,15 @@
+using Prism.Common;
+
+namespace Prism.DryIoc.Maui.Tests.Mocks.ViewModels;
+
+internal class ForcedViewModel
+{
+ public ForcedViewModel(IPageAccessor accessor)
+ {
+ _accessor = accessor;
+ }
+
+ private readonly IPageAccessor _accessor;
+
+ public Page Page => _accessor.Page;
+}
diff --git a/tests/Maui/Prism.DryIoc.Maui.Tests/Mocks/Views/ForcedView.cs b/tests/Maui/Prism.DryIoc.Maui.Tests/Mocks/Views/ForcedView.cs
new file mode 100644
index 0000000000..c606693188
--- /dev/null
+++ b/tests/Maui/Prism.DryIoc.Maui.Tests/Mocks/Views/ForcedView.cs
@@ -0,0 +1,9 @@
+namespace Prism.DryIoc.Maui.Tests.Mocks.Views;
+
+internal class ForcedView : ContentPage
+{
+ public ForcedView()
+ {
+ ViewModelLocator.SetAutowireViewModel(this, ViewModelLocatorBehavior.Forced);
+ }
+}