This is originally a question about Teleriks TabbedWindow control, but its really a generic. Question. In a ItemTemplate, how to I bind to both the view and properties of the viewmodel
Below, my datasource is a list of Views (ie UserControls). I want to have the View presented in the ContentControl and some properties of the viewmodel presented in the header.
<telerik:RadTabbedWindow x:Class="Porter.Application.Views.MainWindow"
...
ItemsSource="{Binding Tabs2}">
<telerik:RadTabbedWindow.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding DataContext.TabHeader}" />
</DataTemplate>
</telerik:RadTabbedWindow.ItemTemplate>
<telerik:RadTabbedWindow.ContentTemplate>
<DataTemplate>
<ContentControl Content="{Binding}" />
</DataTemplate>
</telerik:RadTabbedWindow.ContentTemplate>
</telerik:RadTabbedWindow>
UPDATED RESULT AFTER ANSWER FROM mm8
<telerik:RadTabbedWindow
ItemsSource="{Binding Tabs2}" <!--list of ViewModels (lets say ViewModelBase.cs)-->
...>
<telerik:RadTabbedWindow.Resources>
<DataTemplate DataType="{x:Type acc:SearchAccountsViewModel}">
<acc:SearchAccountsView/>
</DataTemplate>
<DataTemplate DataType="{x:Type hello:HelloWorldViewModel}">
<hello:HelloWorldView/>
</DataTemplate>
</telerik:RadTabbedWindow.Resources>
<telerik:RadTabbedWindow.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding TabHeader}" />
</DataTemplate>
</telerik:RadTabbedWindow.ItemTemplate>
<telerik:RadTabbedWindow.ContentTemplate>
<DataTemplate >
<ContentControl Content="{Binding}" />
</DataTemplate>
</telerik:RadTabbedWindow.ContentTemplate>
</telerik:RadTabbedWindow>
The Tab2
property should return an IEnumerable<T>
where the type T
has some public properties that you bind to in the XAML markup.
It may for example have a TabHeader
property that you bind the header of the tab to in the ItemTemplate
like this:
<telerik:RadTabbedWindow x:Class="Porter.Application.Views.MainWindow"
...
ItemsSource="{Binding Tabs2}">
<telerik:RadTabbedWindow.ItemTemplate>
<DataTemplate>
<TextBlock Text = "{Binding TabHeader}" />
</ DataTemplate >
</ telerik:RadTabbedWindow.ItemTemplate>
</telerik:RadTabbedWindow>
The ContentTemplate
should be resolved automatically provided that you have defined a DataTemplate
for the type T
in scope of the RadTabbedWindow
, for example in your App.xaml
. It's in this template that you add your UserControl
:
<DataTemplate DataType="{x:Type local:YourClass}">
<local:UserControl1 />
</DataTemplate>
You should not create a UserControl
in the view model and add it to Tabs2
. This breaks what the MVVM pattern is all about, i.e. separation of concerns. A view model doesn't create views.
If you don't have/want an implicit DataTemplate
in App.xaml
, you may of course also define the ContentTemplate
inline:
<telerik:RadTabbedWindow x:Class="Porter.Application.Views.MainWindow"
...
ItemsSource="{Binding Tabs2}">
<telerik:RadTabbedWindow.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding TabHeader}" />
</DataTemplate>
</telerik:RadTabbedWindow.ItemTemplate>
<telerik:RadTabbedWindow.ContentTemplate>
<DataTemplate>
<local:UserControl1 />
</DataTemplate>
</telerik:RadTabbedWindow.ContentTemplate>
</telerik:RadTabbedWindow>
The key point is that you bind to properties of T
in both templates and that T
is a POCO and not a control of some kind.