Reputation: 15501
In the current project we work on, we have a main window with several views (each with its own viewmodel) that are presented as items in a tab control. E.g: One tab item is an editor, and contains the editor view as follows:
<TabItem Header="Test Editor">
<TestEditor:TestEditorView DataContext="{Binding TestEditorViewModel}"/>
</TabItem>
Another one shows results:
<TabItem Header="Results Viewer">
<ResultViewer:ResultViewer x:Name="resultViewer1" DataContext="{Binding Path=ResultViewModel}" />
</TabItem>
etc.
I'd like to have the TabItems bound to something in the main window's viewmodel, but I can't figure out how to bind the view's name to any property without breaking the MVVM pattern. I'd like to have something like:
<TabControl.ContentTemplate>
<DataTemplate>
<TestEditor:TestEditorView DataContext ="{Binding TabDataContext}"/>
</DataTemplate>
</TabControl.ContentTemplate>
only with some binding instead of having to know at design time what type will be used as content.
Any ideas?
Upvotes: 2
Views: 5817
Reputation: 132648
Usually I have the TabControl's Tabs stored in the ViewModel
, along with the SelectedIndex
, then I use DataTemplates
to determine which View
to display
View:
<Window>
<Window.Resources>
<DataTemplate DataType="{x:Type ResultViewModel}">
<ResultViewer:ResultViewer />
</DataTemplate>
<DataTemplate DataType="{x:Type EditorViewModel}">
<TestEditor:TestEditorView />
</DataTemplate>
</Window.Resources>
<TabControl ItemsSource="{Binding TabCollection}"
SelectedIndex="{Binding SelectedTabIndex}" />
</Window>
ViewModel:
public class MyViewModel : ViewModelBase
{
publicMyViewModel()
{
TabCollection.Add(new ResultsViewModel());
TabCollection.Add(new EditorViewModel());
SelectedTabIndex = 0;
}
private ObservableCollection<ViewModelBase> _tabCollection
= new ObservableCollection<ViewModelBase>();
public ObservableCollection<ViewModelBase> TabCollection
{
get { return _tabCollection };
}
private int _selectedTabIndex;
public int SelectedTabIndex
{
get { return _selectedTabIndex; }
set
{
if (value != _selectedTabIndex)
{
_selectedTabIndex = value;
RaisePropertyChanged("SelectedTabIndex");
}
}
}
}
Upvotes: 5