Home > Software design >  Get RegionManager in ViewModel
Get RegionManager in ViewModel

Time:10-25

In my project I use Prism for the Views and ViewModels. I now want to load another view into a UserControl in the MainWindowView. I read I can do this with this:

_regionManager.RegisterViewWithRegion("MainRegion", typeof(View));

But unfortunately I have no idea how to get to the instance of IRegionManger in my ViewModel. In all examples I found, other variables are used, but it is not shown where they come from.

This is my View:

<Window x:Class="PortfolioVisualizer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:PortfolioVisualizer"
        mc:Ignorable="d"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="15*"/>
        </Grid.ColumnDefinitions>

        <StackPanel Grid.Column="0">
            <Button Command="{Binding NavigateCommand}" CommandParameter="AddAssetView">
                <StackPanel>
                    <Image/>
                    <Label Content="Add Asset"/>
                </StackPanel>
            </Button>
            <Button Command="{Binding NavigateCommand}" CommandParameter="ConfigView">
                <StackPanel>
                    <Image/>
                    <Label Content="Settings"/>
                </StackPanel>
            </Button>
        </StackPanel>

        <Grid Grid.Column="1">
            <ContentControl prism:RegionManager.RegionName="MainRegion"/>
        </Grid>

    </Grid>
</Window>

This is my ViewModel:

public class MainWindowViewModel : ViewModelBase
    {
        private readonly IRegionManager _RegionManager;

        public DelegateCommand<string> NavigateCommand;
        

        public MainWindowViewModel(IRegionManager regionManager)
        {
            _RegionManager = regionManager;
            NavigateCommand = new DelegateCommand<string>(ExecuteNavigateCommand);
            _RegionManager.RegisterViewWithRegion("MainRegion", typeof(DashboardView));
        }

        private void ExecuteNavigateCommand(string viewName)
        {
            if (string.IsNullOrWhiteSpace(viewName))
                return;

            _RegionManager.RequestNavigate("ContentRegion", viewName);
        }
    }

This is the ViewModdelBase

public class ViewModelBase : BindableBase
    {
        public ViewModelBase()
        {
        
        }
    }

(I know that the ViewModelBase is just superfluous, but there is something to come later)

CodePudding user response:

You have the container inject the region manager like any other dependency:

internal class MyViewModel
{
    public MyViewModel( IRegionManager regionManager )
    {
        regionManager.DoSomeStuff(); // or just put it into a field for later use
    }
}

Note that this only works automatically, if you don't manually new the view model either in code or in xaml. Instead, create it with a factory that is itself injected (e.g. Func<MyViewModel> myViewModelFactory) if you go view model-first (recommended most of the time), or use Prism's ViewModelLocator to have it created as data context if you go view-first.

  • Related