Inspired by this answer, I created a general purpose Shell (Prism, WPF) like this:
<Window x:Class="VRMDataLogger.UI.Shell" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:prism="http://prismlibrary.com/" Title="My App" Height="450" Width="800">
<Grid>
<ContentControl prism:RegionManager.RegionManager="{Binding RegionManager}" prism:RegionManager.RegionName="MainShellRegion" />
</Grid>
</Window>
public partial class Shell : Window
{
public Shell(IRegionManager regionManager, Type contentType)
{
RegionManager = regionManager;
InitializeComponent();
RegionManager.RegisterViewWithRegion("MainShellRegion", contentType);
}
public IRegionManager RegionManager { get; }
}
The initial shell gets created in App.CreateShell():
protected override Window CreateShell()
{
return new Shell(Container.Resolve<IRegionManager>(), typeof(StartScreen));
}
This works fine and the correct view is shown in that initial shell.
I then try to create a second Shell from StartScreenViewModel which shows a different view:
var shell = new Shell(RegionManager.CreateRegionManager(), typeof(MainScreen));
shell.Show();
This opens a new window, but it shows the same view like the first window (StartScreen) instead of MainScreen. What am I doing wrong here?
Not at all. In fact, you get more control over how your view models are created.
When going view-first, your view model is typically created by the
ViewModelLocatorupon navigation and then passedNavigationParameters, if any.If you create your view model manually and bind the view via data templating, you have full control over the creation of the view model. The simplest option is to inject a factory for the view models (like
Func<MainScreenViewModel>) and you get full dependency injection from the container.Of course, you can use a more sophisticated, hand-crafted factory if need be (see this answer).