Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MVVM-datatemplate创建一个新视图_C#_Wpf_Mvvm - Fatal编程技术网

C# MVVM-datatemplate创建一个新视图

C# MVVM-datatemplate创建一个新视图,c#,wpf,mvvm,C#,Wpf,Mvvm,我有两个数据模板,根据当前的ViewModel进行切换。但是,每当我切换ViewModel时,它似乎会调用相应视图的构造函数并在构造函数中调用InitializeComponent()调用,这意味着每当我切换DataTemplate时,它都会生成一个绑定到相应DataTemplate的新视图。我不知道为什么会发生这种情况,但在切换ViewModels时是否有方法阻止创建新视图 下面是位于my MainView的数据模板 <Window.Resources> <DataT

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

下面是位于my MainView的数据模板

<Window.Resources>
    <DataTemplate DataType="{x:Type viewModels:FirstPanelViewModel}">
        <views:FirstPanelView />
    </DataTemplate>
    <DataTemplate DataType="{x:Type viewModels:SecondPanelViewModel}">
        <views:SecondPanelView />
    </DataTemplate>
</Window.Resources>
我的Ioc确保只生成SecondPanelView的一个实例

container.Register<IFirstPanelViewModel, FirstPanelViewModel>(new PerContainerLifetime())
container.Register<ISecondPanelViewModel, SecondPanelViewModel>(new PerContainerLifetime());
这只是调用相应ViewModel的GetInstance

public IFirstViewModel FirstViewModel
{
    get { return _container.GetInstance<IFirstPanelViewModel>(); }
}
public ISecondViewModel SecondViewModel
{
    get { return _container.GetInstance<ISecondPanelViewModel>(); }
}
public IFirstViewModel FirstViewModel
{
获取{return _container.GetInstance();}
}
公共ISecondViewModel第二视图模型
{
获取{return _container.GetInstance();}
}

即使在扩展ContentControl之后,我也无法解决我的问题。我使用这种方法遇到的问题是ContentControl的dependency属性不是直接可接口/可重写的,这迫使我攻击现有的dependency属性。此外,数据模板的初始化似乎比简单的ContentControl更深入

<ContentControl Grid.Row="1" Content="{Binding CurrentViewModel}" />    

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

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

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


这是WPF中的设计。如果视图超出范围,则该视图将被销毁,如果需要再次显示,则必须重新创建该视图。如果使用ViewModel优先方法(也称为DataTemplates),则会发生这种情况。使用带有绑定的源项和数据模板的TabControl也会发生同样的情况。即使未重新创建ViewModel,视图仍会显示。解决这个问题的唯一方法是控制视图的创建方式。这可以在自定义控件中完成。看。你可以试试,但要扩展ContentControl。谢谢你的建议。我来试试这个方法。你的问题似乎涉及到一些基本WPF API之外的基础设施。什么是
容器
?您具体使用什么API?在WPF中,您的问题的答案很简单,您需要确保两个视图都保持实例化,即保持两个视图模型对象都在周围,并且只隐藏/显示相应的对象(例如,将每个视图模型的标志绑定到表示哪个视图模型处于活动状态的视图可见性)。但是,您正在使用的任何其他API都有可能更优雅地实现这一点。当然,还有一个问题是“您为什么在意?”即,按需重新创建视图真的很糟糕吗?如果您有一个列表,并且希望每个项都有不同的视图,该怎么办?因此,UI将只显示活动的。
public IFirstViewModel FirstViewModel
{
    get { return _container.GetInstance<IFirstPanelViewModel>(); }
}
public ISecondViewModel SecondViewModel
{
    get { return _container.GetInstance<ISecondPanelViewModel>(); }
}
<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>