Search code examples
mvvmuwpinversion-of-controltemplate10

Template10 MVVM IoC Inject ViewModel into Shell View


I'm looking for the best way to inject a ViewModel into a Shell view.

I'm using Autofac (but I can adopt code from other IoC containers if sample is available). I have got the other VMs injecting correctly - but the method that resolves the VM using ResoleForPage method of the App class.

I'm fairly new to UWP developement and any help is greatly appreciated!


Solution

  • Passing a ViewModel to the Shell is indeed simpler than passing it to the other pages, because the Shell is the only page that is created explicitly by us: so, it should be enough to add a parameter to the constructor of the Shell of type ShellViewModel:

        public Shell()
        {
            Instance = this;
            this.InitializeComponent();
        }
    
        public Shell(INavigationService navService, ShellViewModel model) : this()
        {
            navigationMenu.NavigationService = navService;
            navigationMenu.RefreshStyles(App.Current.RequestedTheme, true);
            this.DataContext = model;
        }
    

    then expose the DataContext in a strongly typed way, as with any other pages (useful mainly if you use x:Bind bindings in xaml):

        public ShellViewModel ViewModel => DataContext as ShellViewModel;
    

    And now you just have to pass an instance of your ViewModel class, pulling it from your IoC container, when you create the Shell. In the latest Template 10 template for VS2017, it should be in the CreateRootElement method of the App class:

        public override UIElement CreateRootElement(IActivatedEventArgs e)
        {
            var service = NavigationServiceFactory(BackButton.Attach, ExistingContent.Include);
            return new Template10.Controls.ModalDialog
            {
                DisableBackButtonWhenModal = true,
                Content = new Shell(service, new ShellViewModel()),
            };
        }
    

    of course replacing new ShellViewModel() with the code to pull it from Autofac.