受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
。我在这里做什么错了?
答案 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)。