2016-07-19 76 views
1

我有兩個DataTemplates根據當前ViewModel進行切換。然而,每當我轉我的視圖模型,它似乎調用相應的視圖的構造函數,並調用構造函數,這意味着每當我切換的DataTemplate,它生成綁定到相應的DataTemplate一個新視圖內的在InitializeComponent()調用。我不知道爲什麼會發生這種情況,但是在切換ViewModels時是否有辦法阻止創建新視圖?MVVM - datatemplate創建一個新視圖

下面是位於我的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>(); } 
} 
+3

這是在WPF設計。如果視圖超出範圍,視圖將被銷燬,如果需要再次顯示,則必須重新創建視圖。如果你使用ViewModel的第一種方法,就會發生這種情況,也就是DataTemplates。使用帶綁定源項目和數據模板的TabControl也會發生同樣的情況。即使ViewModel沒有被重新創建,視圖也是如此。解決這個問題的唯一方法是控制視圖的創建方式。這可以在自定義控件中完成。見[這裏](http://stackoverflow.com/questions/3877611/is-it-possible-to-cache-the-view-when-using-model-first-approach)。 – Michael

+0

你可以嘗試[this](http://stackoverflow.com/questions/9794151/stop-tabcontrol-from-recreating-its-children),而是通過擴展ContentControl來代替。 – Michael

+0

感謝您的建議。我會給這個方法一個去。 – kotsumu

回答

0

即使在擴展ContentControl之後,我仍然無法解決我的問題。我遇到了使用這種方法的問題,ContentControl的依賴項屬性不是直接可交織/可重寫的,這迫使我破解現有的依賴屬性。此外,DataTemplate的初始化似乎比簡單的ContentControl更深入。

所以我決定改變我的觀點正在被簡單地切換自己的知名度顯示方式。這種方法對我來說很有用,因爲我基本上希望我的觀點能夠保持在自己的位置,並隨時可以在之前的狀態下進行界面連接。

1

這是一個老問題,但我也有這個問題掙扎。答案是將視圖實例直接放置在資源中,並將它們綁定到數據模板中的內容控件。如果你這樣做,視圖只實例化一次。

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