2016-07-19 2 views
1

У меня есть два DataTemplates, которые переключаются в зависимости от текущего ViewModel. Однако всякий раз, когда я переключаю свой ViewModel, он, как представляется, вызывает соответствующий конструктор View и вызывает вызов InitializeComponent() внутри конструктора, а это означает, что всякий раз, когда я переключаю DataTemplate, он генерирует новое представление, привязанное к соответствующему DataTemplate. Я не уверен, почему это происходит, но есть ли способ предотвратить создание нового представления при переключении ViewModels?MVVM - datatemplate создает новый вид

Ниже приведены DataTemplates, расположенные в моем 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}" 

Это просто вызов GetInstance соответствующей ViewModel.

public IFirstViewModel FirstViewModel 
{ 
    get { return _container.GetInstance<IFirstPanelViewModel>(); } 
} 
public ISecondViewModel SecondViewModel 
{ 
    get { return _container.GetInstance<ISecondPanelViewModel>(); } 
} 
+3

Это дизайн в WPF. Если представление выходит за пределы видимости, представление уничтожается и должно быть воссоздано, если его нужно снова отобразить. Это происходит, если вы используете первый подход ViewModel, a.k.a. 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> 
Смежные вопросы