Search code examples
mauiprism

prism:ViewModelLocator.AutowireViewModel doesnt work with contentviews


I'm migrating a Xamarin.Forms app that uses Prism to .NET Maui. The app has a TabbedPage navigation. This migration works. But the ContentPages contain several ContentViews like so:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:views="clr-namespace:MauiDemo.Views"
             x:Class="MauiDemo.Views.HomePage"
             Title="HomePage">
  <VerticalStackLayout>
    <views:FirstContentView HeightRequest="200"/>
    <views:SecondContentView HeightRequest="200"/>
  </VerticalStackLayout>
</ContentPage>

In Xamarin I was able to add the prism:ViewModelLocator.Autowire="true" attribute to the contentview and prism found the associated viewmodel. In .NET maui the prism:ViewModelLocator.AutowireViewModel="Automatic" property makes nothing.

For example, the name of the ContentView is "FirstContentView". The name of the associated viewModel is "FirstContentViewViewModel"

According the description in https://prismlibrary.com/docs/maui/migrating.html it should work, but it doesnt.

Whats the trick to configuring such a auto wiring?

I use a current clone of the prism repo https://github.com/PrismLibrary/Prism and a current .NET8 SDK with the newest MAUI assemblies


Solution

  • I works with regions and not via autowiring. The Page with the different ContentViews should look like

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:views="clr-namespace:MauiDemo.Views"
                 xmlns:prism="http://prismlibrary.com"
                 x:Class="MauiDemo.Views.HomePage"
                 Title="HomePage">
      <VerticalStackLayout>
        <ContentView prism:RegionManager.RegionName="FirstContent"/>
        <ContentView  prism:RegionManager.RegionName="SecondContent"/>
      </VerticalStackLayout>
    </ContentPage>
    

    The desired view with its viewmodel should be registered in the MauiProgram as RegisterForRegionNavigation

    container.RegisterForRegionNavigation<FirstContentView, FirstContentViewViewModel>();
    container.RegisterForRegionNavigation<SecondContentView, SecondContentViewModel>();
    
    .UsePrism(prism =>
    {
        prism.RegisterTypes(container =>
        {
            container.RegisterForNavigation<MainPage,MainPageViewModel>();
            container.RegisterForNavigation<HomePage>();
    
            container.RegisterForRegionNavigation<FirstContentView, FirstContentViewViewModel>();
            container.RegisterForRegionNavigation<SecondContentView, SecondContentViewModel>();
    
        })
        .CreateWindow(navigationService => navigationService.CreateBuilder()
        .AddSegment<MainPage>()
        .NavigateAsync(HandleNavigationError));
    })
    

    The ViewModel of the page that containing the several ContentViews should call the RegionManager.RequestNavigate method for the needed ContentViews.

    public class HomePageViewModel : ViewModelBase, IInitialize
    {
        private readonly IRegionManager _regionManager;
    
        public HomePageViewModel(IRegionManager regionManager)
        {
            _regionManager = regionManager;
        }
    
        public void Initialize(INavigationParameters parameters)
        {
            _regionManager.RequestNavigate("FirstContent", nameof(FirstContentView));
            _regionManager.RequestNavigate("SecondContent", nameof(SecondContentView));
        }
    }
    

    Thats all. It works as described at https://xamgirl.com/prism-regions-in-xamarin-forms/