Prism / WPF中的新外壳/窗口显示错误的视图

时间:2019-05-27 14:08:25

标签: wpf mvvm prism prism-7

this answer的启发,我创建了一个通用的Shell(Prism,WPF),如下所示:

<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; }
}

初始外壳在App.CreateShell()中创建:

protected override Window CreateShell()
{
    return new Shell(Container.Resolve<IRegionManager>(), typeof(StartScreen));
}

这很好,并且在初始外壳中显示了正确的视图。

然后我尝试从StartScreenViewModel创建另一个显示不同视图的Shell:

var shell = new Shell(RegionManager.CreateRegionManager(), typeof(MainScreen));
shell.Show();

这将打开一个新窗口,但显示的是与第一个窗口(StartScreen)相同的视图,而不是MainScreen。我在这里做什么错了?

2 个答案:

答案 0 :(得分:0)

尝试为每个外壳使用唯一的区域名称:

public partial class Shell : Window
{
    public Shell(IRegionManager regionManager, Type contentType)
    {
        RegionManager = regionManager;
        InitializeComponent();
        MainRegionName = Guid.NewGuid().ToString();
        RegionManager.RegisterViewWithRegion(MainRegionName, contentType);
    }

    public string MainRegionName { get; }
    public IRegionManager RegionManager { get; }

}

XAML:

<ContentControl prism:RegionManager.RegionManager="{Binding RegionManager}"
                prism:RegionManager.RegionName="{Binding MainRegionName, RelativeSource={RelativeSource AncestorType=Window}}" />

答案 1 :(得分:0)

  

因此,我也在考虑摆脱该地区的问题。但是我认为这样做会失去的是将依赖项注入到视图模型中的好功能

一点也不。实际上,您可以更好地控制视图模型的创建方式。

首先进入视图时,视图模型通常由ViewModelLocator在导航时创建,然后传递NavigationParameters(如果有)。

如果手动创建视图模型并通过数据模板绑定视图,则可以完全控制视图模型的创建。最简单的选择是为视图模型注入工厂(例如Func<MainScreenViewModel>),然后从容器中获得完全的依赖注入。

internal class StartScreenViewModel
{
    public StartScreenViewModel( Func<MainScreenViewModel> mainScreenViewModelFactory )
    {
        GoToMainScreenCommand = new DelegateCommand( () => new Shell( mainScreenViewModelFactory() ).Show() );
    }

    public DelegateCommand GoToMainScreenCommand { get; }
}

当然,如果需要,您可以使用更复杂的手工制作工厂(请参见this answer)。