MVVM-datatemplate创建一个新视图

本文关键字:一个 新视图 创建 MVVM-datatemplate | 更新日期: 2023-09-27 17:57:56

我有两个数据模板,它们根据当前ViewModel进行切换。但是,每当我切换ViewModel时,它似乎都会调用相应View的构造函数,并在构造函数中调用InitializeComponent()调用,这意味着每当我切换DataTemplate时,它都会生成一个绑定到相应DataTemplate的新视图。我不知道为什么会发生这种情况,但在切换ViewModels时,有没有办法防止创建新视图?

以下是位于我的MainView中的数据模板。

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

MVVM-datatemplate创建一个新视图

这是一个老问题,但我也在为这个问题而挣扎。答案是将视图实例直接放置在资源中,并将它们绑定到数据模板中的内容控件。如果这样做,则视图只实例化一次。

<Window.Resources>
    <views:FirstPanelView x:Key="FirstPanelViewKey"/>
    <views:SecondPanelView x:Key="SecondPanelViewKey"/>
    <DataTemplate x:Key="DT1">
        <ContentControl Content="{StaticResource FirstPanelViewKey}" />
    </DataTemplate>
    <DataTemplate x:Key="DT2">
        <ContentControl Content="{StaticResource SecondPanelViewKey}" />
    </DataTemplate>
</Window.Resources>

即使扩展了ContentControl,我也无法解决问题。我在使用这种方法时遇到的问题是,ContentControl的依赖属性不是直接可交互/可重写的,这迫使我破解现有的依赖属性。此外,DataTemplate的初始化似乎比简单的ContentControl更深。

因此,我决定通过简单地切换视图的可见性来改变视图的显示方式。这种方法对我很有效,因为我基本上希望我的观点留在后台做自己的事情,并随时准备在以前的状态下进行交互。