【发布时间】:2016-11-22 22:53:36
【问题描述】:
我有两个根据当前 ViewModel 切换的 DataTemplate。但是,每当我切换 ViewModel 时,它似乎会调用相应视图的构造函数并调用构造函数中的 InitializeComponent() 调用,这意味着 每当我切换 DataTemplate 时,它都会生成一个绑定到相应 DataTemplate 的新视图。我不确定为什么会发生这种情况,但有没有办法在切换 ViewModel 时阻止创建新视图?
下面是位于我的 MainView 中的 DataTemplates。
<Window.Resources>
<DataTemplate DataType="{x:Type viewModels:FirstPanelViewModel}">
<views:FirstPanelView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:SecondPanelViewModel}">
<views:SecondPanelView />
</DataTemplate>
</Window.Resources>
模板正在 ContentControl 中显示。
<ContentControl Grid.Row="1" Content="{Binding CurrentViewModel}" />
这是我的SecondPanelView,和我的FirstPanelView一样,很简单。
public partial class FirstPanelView
{
public FirstPanelView()
{
InitializeComponent();
}
}
public partial class SecondPanelView
{
public SecondPanelView()
{
InitializeComponent();
}
}
我的 Ioc 确保我只生成一个 SecondPanelView 实例
container.Register<IFirstPanelViewModel, FirstPanelViewModel>(new PerContainerLifetime())
container.Register<ISecondPanelViewModel, SecondPanelViewModel>(new PerContainerLifetime());
DataContext 在每个视图中都由自定义标记扩展限定。
DataContext="{Binding Source={common:Locate}, Path=FirstPanelViewModel}"
DataContext="{Binding Source={common:Locate}, Path=SecondPanelViewModel}"
这只是调用相应 ViewModel 的 GetInstance。
public IFirstViewModel FirstViewModel
{
get { return _container.GetInstance<IFirstPanelViewModel>(); }
}
public ISecondViewModel SecondViewModel
{
get { return _container.GetInstance<ISecondPanelViewModel>(); }
}
【问题讨论】:
-
这是 WPF 设计的。如果视图超出范围,则视图将被销毁,如果需要再次显示,则必须重新创建。如果您使用 ViewModel 第一种方法,也就是 DataTemplates,就会发生这种情况。使用带有绑定源项和数据模板的 TabControl 也会发生同样的事情。即使 ViewModel 没有重新创建,视图也是如此。解决这个问题的唯一方法是让控制视图的创建方式。这可以在自定义控件中完成。见here。
-
您可以尝试this,但改为扩展 ContentControl。
-
感谢您的建议。我会试试这个方法。
-
您的问题似乎涉及基本 WPF API 之外的一些基础设施。
container是什么?您具体使用的是什么 API?在 WPF 中,您的问题的答案很简单,您需要确保两个视图都保持实例化,即保留两个视图模型对象,并隐藏/显示适当的对象(例如,将每个视图模型的标志绑定到视图的可见性,表示哪个是活动的)。但是您使用的任何其他 API 都可以更优雅地完成此操作。 -
当然,还有“你为什么关心?”的问题。 IE。按需重新创建视图真的有那么糟糕吗?