In WPF if you want to move a view from one window to another, using DataTemplates will cause the view to be destroyed and recreated in the new window, which means all view state info that is not bound gets lost.
The most obvious one is scrollbar position, however I have more complex stuff in my case.
In order to avoid this, I want to keep a cache of view and view model pairs which I can pass around without the view getting recreated.
I have a class like this:
public class ViewModelPair
{
public IViewModel ViewModel { get; set; }
public UserControl View { get; set; }
}
which is stored as ObservableCollection<ViewModelPair> ViewModels { get; set; } in the main window view model.
Each view/view model pair has a DataTemplate defined like this:
<DataTemplate DataType="{x:Type vm:MyViewModel}">
<v:MyView />
</DataTemplate>
However, if I want to use a TabControl, I cannot bind the content to the view and view model properties.
I want to do something like this:
<TabControl ItemsSource="{Binding ViewModels}">
<TabControl.ContentTemplate>
<DataTemplate DataType="{x:Type vm:ViewModelPair}">
<ContentPresenter DataContext="{Binding ViewModel}"
Content="{Binding View}" />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
However, this gives throws binding errors:
ViewModel property not found on object of type ContentControl
and
View property not found on object of type ContentControl
If I do <ContentPresenter Content="{Binding}" /> this binding works, but I just see the name of the ViewModelPair object as the DataTemplate doesn't exist for ViewModelPair (it only exists for the child View and ViewModel types.
How could I achieve this desired behaviour where can I keep the view and view model cached together, and have this work with a TabControl/TabItem?
DataTemplatewithDataType. Besides that, storing references to views in a view model is not MVVM.