Prism/WPF 中的新 shell/window 显示错误视图
New shell/window in Prism/WPF shows wrong view
受到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; }
}
初始 shell 在 App.CreateShell()
中创建:
protected override Window CreateShell()
{
return new Shell(Container.Resolve<IRegionManager>(), typeof(StartScreen));
}
这工作正常,正确的视图显示在初始 shell。
然后我尝试从 StartScreenViewModel
创建第二个 Shell,它显示不同的视图:
var shell = new Shell(RegionManager.CreateRegionManager(), typeof(MainScreen));
shell.Show();
这会打开一个新的 window,但它显示的视图与第一个 window(StartScreen
)相同,而不是 MainScreen
。我在这里做错了什么?
尝试为每个 shell:
使用唯一的区域名称
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}}" />
So I was thinking about getting rid of the region stuff too. But I think what I'll lose by doing so is the nice feature of dependency injection into my view models
完全没有。事实上,您可以更好地控制视图模型的创建方式。
当转到 view-first 时,您的视图模型通常由 ViewModelLocator
在导航时创建,然后传递给 NavigationParameters
,如果有的话。
如果您手动创建视图模型并通过数据模板绑定视图,则您可以完全控制视图模型的创建。最简单的选择是为视图模型注入工厂(如 Func<MainScreenViewModel>
),然后从容器中获得完整的依赖注入。
internal class StartScreenViewModel
{
public StartScreenViewModel( Func<MainScreenViewModel> mainScreenViewModelFactory )
{
GoToMainScreenCommand = new DelegateCommand( () => new Shell( mainScreenViewModelFactory() ).Show() );
}
public DelegateCommand GoToMainScreenCommand { get; }
}
当然,如果需要,您可以使用更复杂的 hand-crafted 工厂(参见 )。
受到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; }
}
初始 shell 在 App.CreateShell()
中创建:
protected override Window CreateShell()
{
return new Shell(Container.Resolve<IRegionManager>(), typeof(StartScreen));
}
这工作正常,正确的视图显示在初始 shell。
然后我尝试从 StartScreenViewModel
创建第二个 Shell,它显示不同的视图:
var shell = new Shell(RegionManager.CreateRegionManager(), typeof(MainScreen));
shell.Show();
这会打开一个新的 window,但它显示的视图与第一个 window(StartScreen
)相同,而不是 MainScreen
。我在这里做错了什么?
尝试为每个 shell:
使用唯一的区域名称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}}" />
So I was thinking about getting rid of the region stuff too. But I think what I'll lose by doing so is the nice feature of dependency injection into my view models
完全没有。事实上,您可以更好地控制视图模型的创建方式。
当转到 view-first 时,您的视图模型通常由 ViewModelLocator
在导航时创建,然后传递给 NavigationParameters
,如果有的话。
如果您手动创建视图模型并通过数据模板绑定视图,则您可以完全控制视图模型的创建。最简单的选择是为视图模型注入工厂(如 Func<MainScreenViewModel>
),然后从容器中获得完整的依赖注入。
internal class StartScreenViewModel
{
public StartScreenViewModel( Func<MainScreenViewModel> mainScreenViewModelFactory )
{
GoToMainScreenCommand = new DelegateCommand( () => new Shell( mainScreenViewModelFactory() ).Show() );
}
public DelegateCommand GoToMainScreenCommand { get; }
}
当然,如果需要,您可以使用更复杂的 hand-crafted 工厂(参见