如何在TabControl.ContentTemplate中添加新的用户控件?

时间:2022-12-17 23:57:23

I am little stuck with adding new instances of a usercontrol in a TabControl.ContentTemplate?

我很难在TabControl.ContentTemplate中添加新的usercontrol实例?

My Xaml is here:

我的Xaml在这里:

<TabControl ItemsSource="{Binding Tables}">
    <TabControl.ItemTemplate>
        <DataTemplate>

        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <DataTemplate DataType="{x:Type uc:mytest1}">
            <uc:mytest1>

            </uc:mytest1>
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>

I am binding TabControl.ItemsSource property to an ObservableCollection and in the content template I am adding a user control, but when this app runs I am getting new items as TabItems but the content page is holding same user control, but I want new user controls to be added for each new TabItem.

我将TabControl.ItemsSource属性绑定到ObservableCollection,在内容模板中我添加了一个用户控件,但是当这个应用程序运行时,我将新项目作为TabItems但内容页面持有相同的用户控件,但我想要新的用户控件要为每个新TabItem添加。

I am very new to the WPF and may be I am doing a very basic mistake, kindly guide me.

我对WPF很新,可能是我犯了一个非常基本的错误,请指导我。

2 个解决方案

#1


7  

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.

ControlTemplate确定选项卡控件的元素的外观,这些元素不是单个选项卡项的一部分。 ItemTemplate处理各个选项卡项的内容。另外,TabItem是一个带标题的内容控件,这意味着它有两个内容类型属性Content和Header,带有两个独立的模板ContentTemplate和HeaderTemplate。为了能够使用绑定填充选项卡项,您需要使用上述属性设置TabItem的样式。

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;
    }
}

#2


4  

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.

Saurabh,当您设置Template,通常是DataTemplate,ControlTemplate等时,这些模板中的可视元素将在WPF中以UI Virtualization的概念重用。 TabControl通常一次只显示一个项目,因此它不会为每个选项卡项创建新的Visual Item,而只会更改该DataContext并刷新“Selected Visual Item”的绑定。它的加载/卸载事件被触发,但对象始终相同。

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.

您可以使用加载/卸载事件并相应地编写代码作为您的用户控件的“可视元素”,以便控件应该是无状态的并且不依赖于旧数据。应用新的DataContext后,您应该刷新所有内容。

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

DataContextChanged,Loaded和Unloaded事件可以帮助您删除旧数据的所有依赖项。

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

否则,您手动创建一个新的TabItem,并将UserControl作为其子项,并将其添加到TabControl中,而不是添加数据项。

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

手动添加TabItem将为每个项目创建新控件,在选定区域中,将根据选择显示不同的元素。

#1


7  

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.

ControlTemplate确定选项卡控件的元素的外观,这些元素不是单个选项卡项的一部分。 ItemTemplate处理各个选项卡项的内容。另外,TabItem是一个带标题的内容控件,这意味着它有两个内容类型属性Content和Header,带有两个独立的模板ContentTemplate和HeaderTemplate。为了能够使用绑定填充选项卡项,您需要使用上述属性设置TabItem的样式。

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;
    }
}

#2


4  

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.

Saurabh,当您设置Template,通常是DataTemplate,ControlTemplate等时,这些模板中的可视元素将在WPF中以UI Virtualization的概念重用。 TabControl通常一次只显示一个项目,因此它不会为每个选项卡项创建新的Visual Item,而只会更改该DataContext并刷新“Selected Visual Item”的绑定。它的加载/卸载事件被触发,但对象始终相同。

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.

您可以使用加载/卸载事件并相应地编写代码作为您的用户控件的“可视元素”,以便控件应该是无状态的并且不依赖于旧数据。应用新的DataContext后,您应该刷新所有内容。

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

DataContextChanged,Loaded和Unloaded事件可以帮助您删除旧数据的所有依赖项。

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

否则,您手动创建一个新的TabItem,并将UserControl作为其子项,并将其添加到TabControl中,而不是添加数据项。

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

手动添加TabItem将为每个项目创建新控件,在选定区域中,将根据选择显示不同的元素。