How to add new user control in TabControl.ContentTemplate?

一笑奈何 提交于 2019-12-03 16:23:53

The ControlTemplate determines the appearance of the elements of the tab control that are not part of the individual tab items. The ItemTemplate handles the content of the individual tab items. Additionally, a TabItem is a headered content control, which means it has two content type properties Content and Header with two separate templates ContentTemplate and HeaderTemplate. In order to be able to populate the tab items using binding, you need to style the TabItem using the above properties.

Example:

<Window x:Class="Example.Window2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Name="Window"
    Title="Window2" Height="300" Width="300">
    <Window.DataContext>
        <Binding ElementName="Window" Path="VM"/>
    </Window.DataContext>
    <Window.Resources>
        <DataTemplate x:Key="TabItemHeaderTemplate">
            <Grid>
                <TextBlock Text="{Binding Header}"/>
                <Ellipse Fill="Red" Width="40" Height="40" Margin="0,20,0,0"/>
            </Grid>
        </DataTemplate>
        <DataTemplate x:Key="TabItemContentTemplate">
            <Ellipse Fill="Green"/>
        </DataTemplate>
        <Style x:Key="TabItemContainerStyle" TargetType="TabItem">
            <Setter Property="Header" Value="{Binding}"/>
            <Setter Property="HeaderTemplate" 
                    Value="{StaticResource TabItemHeaderTemplate}"/>
            <Setter Property="Content" Value="{Binding}"/>
            <Setter Property="ContentTemplate" 
                    Value="{StaticResource TabItemContentTemplate}"/>
        </Style>
    </Window.Resources>
    <Grid>
        <TabControl ItemsSource="{Binding Items}" 
                    ItemContainerStyle="{StaticResource TabItemContainerStyle}"/>
    </Grid>
</Window>

The code behind:

public partial class Window2 : Window
{
    public TabControlVM VM { get; set; }

    public Window2()
    {
        VM = new TabControlVM();
        InitializeComponent();
    }
}

And the view model classes:

public class TabControlVM
{
    public ObservableCollection<TabItemVM> Items { get; set; }

    public TabControlVM()
    {
        Items = new ObservableCollection<TabItemVM>();
        Items.Add(new TabItemVM("tabitem1"));
        Items.Add(new TabItemVM("tabitem2"));
        Items.Add(new TabItemVM("tabitem3"));
        Items.Add(new TabItemVM("tabitem4"));
    }
}

public class TabItemVM
{
    public string Header { get; set; }

    public TabItemVM(string header)
    {
        Header = header;
    }
}

Saurabh, When you set Template, usually DataTemplate, ControlTemplate etc, the visual elements inside these templates are reused in WPF with concept of UI Virtualization. TabControl typically displays only one item at a time, so it does not create new Visual Item for every tab item, instead it only changes that DataContext and refreshes bindings of "Selected Visual Item". Its loaded/unloaded events are fired, but the object is same always.

You can use loaded/unload events and write your code accordingly that your "Visual Element" which is your usercontrol, so that control should be stateless and is not dependent on old data. When new DataContext has applied you should refresh everything.

DataContextChanged, Loaded and Unloaded events can help you remove all dependencies on old data.

Otherwise, you an create a new TabItem manually with your UserControl as its Child and add it in TabControl instead of adding Data Items.

Adding TabItems manually will create new control for every item and in selected area different elements will appear based on selection.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!