1

I want a TabControl where each tab item represents a (Employee)ViewModel; the header should be the DisplayName property of that view model, and the content should be a user control (EmployeeDetailsView) that has a data context of the view model.

So pidgeon xaml (is there such a thing??):

<TabControl x:Name="Items">
    <TabItem Header="DisplayName" Content=local:EmployeeDetailsView />
<TabControl>

What should my real XAML look like?

Cheers,
Berryl

EDIT for Vortex

        <TabControl x:Name="Items" >
            <TabControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding DisplayName}" />
                </DataTemplate>
            </TabControl.ItemTemplate>
            <TabControl.ContentTemplate>
                <DataTemplate>
                    <ContentControl>
                        <local:EmployeeDetailView/>
                    </ContentControl>
                </DataTemplate>
            </TabControl.ContentTemplate>
         </TabControl>
Berryl
  • 12,471
  • 22
  • 98
  • 182

1 Answers1

3

In WPF it is quite simple. But in silverlight I used custom TabControl.

Silverlight

You can find source and example here (MyTabControl.cs), where I've answered a similar question.

And now your code must be something like:

<my:MyTabControl x:Name="myTabs" MyItemsSource="{Binding Items}" MySelectedItem="{Binding SelectedItem}" >
    <my:MyTabControl.TabHeaderItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding DisplayName}" />
        </DataTemplate>
    </my:MyTabControl.TabHeaderItemTemplate>
    <my:MyTabControl.TabItemTemplate>
        <DataTemplate>
            <local:EmployeeDetailsView />
        </DataTemplate>
    </my:MyTabControl.TabItemTemplate>
</my:MyTabControl> 

In code-behind or somewhere:

var items = new List<Employee>(){
                new Employee{DisplayName = "Employee 1"},
                new Employee{DisplayName = "Employee 2"}};

myTabs.DataContext = new SomeCollectionModel
{
      Items = items,
      SelectedItem = items[0]
};

WPF

WPF has built-in support of DataTemplates in the TabControl, so I have to do a few minor changes in XAML:

<TabControl x:Name="myTabs" ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding DisplayName}" />
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <DataTemplate>
            <local:EmployeeDetailsView />
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>
Community
  • 1
  • 1
vortexwolf
  • 13,967
  • 2
  • 54
  • 72
  • Awesome. Do I need to have the EmployeeDetailsView user control as a resource somewhere (it is in a xmlns aliased as "local")? I can't bind to it directly – Berryl Feb 09 '11 at 19:53
  • Oh, I see. I can just wrap it in the content control declaratively: – Berryl Feb 09 '11 at 20:01
  • @Berryl EmployeeDetailsView is a property of a ViewModel and it is supposed to be created in code. For example, items[0].EmployeeDetailsView = new SomeUserControlView(); Also you can get from resource, this.Resources "controlResourceKey" – vortexwolf Feb 09 '11 at 20:07
  • @Berryl I've dismissed, I thought you wanted to show different views in different tabs. If the view is the same for all tabs, you can write it in this way – vortexwolf Feb 09 '11 at 20:12
  • Hi vortex, each tab will be either a new or existing employee represented by EmployeeViewModel. I posted the code I have currently at the end of my original question - are you saying there is a better way to write this? – Berryl Feb 09 '11 at 21:17
  • @Berryl Just remove the ControlTemplate tags. I have edited my answer. – vortexwolf Feb 09 '11 at 21:40