Вопрос по wpf, tabcontrol, templates – Как добавить новый пользовательский элемент управления в TabControl.ContentTemplate?

4

Я немного застрял с добавлением новых экземпляров usercontrol вTabControl.ContentTemplate?

Мой 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>

Я обязываюTabControl.ItemsSource собственность наObservableCollection и в шаблоне контента я добавляю пользовательский элемент управления, но при запуске этого приложения я получаю новые элементы какTabItemс, но страница содержимого содержит тот же пользовательский элемент управления, но я хочу, чтобы новые элементы управления добавлялись для каждого новогоTabItem.

Я очень новичок в WPF и, возможно, я делаю очень элементарную ошибку, будьте любезны.

Ваш Ответ

2   ответа
7

ControlTemplate определяет внешний вид элементов элемента управления вкладками, которые не являются частью отдельных элементов вкладки.ItemTemplate обрабатывает содержимое отдельных элементов вкладки. Кроме того,TabItem является заголовочным элементом управления контентом, что означает, что он имеет два свойства типа контентаContent а такжеHeader с двумя отдельными шаблонамиContentTemplate а такжеHeaderTemplate, Чтобы можно было заполнять элементы вкладок с помощью привязки, необходимоTabItem используя вышеуказанные свойства.

Пример:

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

Код позади:

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

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

И просмотр модели классов:

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

Когда вы устанавливаете Template, обычно DataTemplate, ControlTemplate и т. Д., Визуальные элементы внутри этих шаблонов повторно используются в WPF с концепцией виртуализации пользовательского интерфейса. TabControl обычно отображает только один элемент за раз, поэтому он не создает новый визуальный элемент для каждого элемента вкладки, вместо этого он только изменяет этот DataContext и обновляет привязки «выбранного визуального элемента». Загруженные / выгруженные события запускаются, но объект всегда один и тот же.

Вы можете использовать события загрузки / выгрузки и написать свой код соответственно вашему «визуальному элементу», который является вашим пользовательским контролем, так что контроль должен быть без сохранения состояния и не зависеть от старых данных. Когда новый DataContext применяется, вы должны обновить все.

События DataContextChanged, Loaded и Unloaded могут помочь вам удалить все зависимости от старых данных.

В противном случае вы создаете новый TabItem вручную, используя UserControl в качестве дочернего элемента, и добавляете его в TabControl вместо добавления элементов данных.

Добавление TabItems вручную создаст новый элемент управления для каждого элемента, и в выбранной области появятся различные элементы в зависимости от выбора.

Похожие вопросы