Search code examples
wpfviewtabs

How to display a view for the tab?


I have a collection of Tabs in my main View Model. Every Tab pepresented by a class with several properties:

class SettingTab : ISettingTab
{
    public string Name { get; }

    readonly UIInfo UIInfo;
    public Type TypeView => UIInfo.TypeView;

    public Func<IViewModel> ViewModel => UIInfo.ViewModel;
    #endregion

    #region Constructor

    public SettingTab(string Name, UIInfo UIInfo)
    {
        this.Name = Name;
        this.UIInfo = UIInfo;
    }
}

}

How can I display a particular view when selecting a particlular tab? Can you please say what should I add here

<TabControl ItemsSource="{Binding Tabs}"
        TabStripPlacement="Left"
        SelectedIndex="{Binding SelectedIndex}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}"/>
        </DataTemplate>
</TabControl>

Solution

  • The TabControl displays a list of TabItem elements, the tab headers, and the TabControl.SelectedContent, that references the TabItem.Content of the selected item, as the actual tab content.
    By default the TabItem.Content is the DataContext of the TabItem - in your case it's the Tab data model.
    This means, the DataTemplate of the TabControl.Itemtemplate and the TabControl.ContentTemplate share the same DataContext by default.
    If you want to change the this default behavior, e.g., make a particular property on this DataContext as the TabControl.SelectedContent, you must specify this binding in the TabControl.ItemContainersStyle.

    For example, if each of your Tab data item has a Tab.ViewModel property that you want to display as the TabControl.SelectedContent, then bind the TabItem.Content property to this Tab.ViewModel data property. Additionally, you have to define a TabControl.ContentTemplate for the data type of the Tab.ViewModel property to define the layout for the TabControl.SelectedContent:

    <TabControl ItemsSource="{Binding Tabs}">
      <TabControl.Resources>
    
        <!-- Implicit DataTemplate for TabControl's content -->
        <DataTemplate DataType="{x:Type TypeOfTheViewModelPropertyOnTheTabType}">
          ...
        </DataTemplate>
      </TabControl.Resources>
      <TabControl.ItemContainerStyle>
        <Style TargetType="TabItem">
    
          <!-- Make the property value of 'Tab.ViewModel' the DataContext of the content -->
          <Setter Property="Content" Value="{Binding ViewModel}" />
        </Style>
      </TabControl.ItemContainerStyle>
    
      <TabControl.ItemTemplate>
        <DataTemplate DataType="{x:Type Tab}">
          <TextBlock Text="{Binding Name}" />
        </DataTemplate>
      </TabControl.ItemTemplate>
    </TabControl>