Wasabi
Wasabi

Reputation: 3061

Creating a Tab template in xaml

I am trying to create a WPF tabbed window which will contain a dynamic number of tabs. Each of the tabs, however, will be identically formatted and contain the same controls (not the same instances, but the same class of controls). Each of the tabs will have the following form:

    <TabItem>
        <TabItem.Header>
            <TextBlock>C1</TextBlock>
        </TabItem.Header>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
            </Grid.RowDefinitions>

            <Grid Grid.Row="1" Grid.Column="0">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"></ColumnDefinition>
                    <ColumnDefinition Width="Auto"></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition Width="Auto"></ColumnDefinition>
                    <ColumnDefinition Width="Auto"></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <Label Grid.Column="0">Ancorage</Label>
                <ComboBox Grid.Column="1" Width="65" SelectedIndex="1">
                    <ComboBoxItem>Active</ComboBoxItem>
                    <ComboBoxItem>Passive</ComboBoxItem>
                </ComboBox>

                <Label Grid.Column="3" HorizontalAlignment="Right">Ancorage</Label>
                <ComboBox Grid.Column="4" Width="65" HorizontalAlignment="Right">
                    <ComboBoxItem>Active</ComboBoxItem>
                    <ComboBoxItem>Passive</ComboBoxItem>
                </ComboBox>
            </Grid>
            <Grid Grid.Row="2">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"></ColumnDefinition>
                    <ColumnDefinition Width="Auto"></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <Label Grid.Column="0"># Sections</Label>
                <xctk:IntegerUpDown Grid.Column="1" Minimum="3" Value="3" ></xctk:IntegerUpDown>
            </Grid>
        </Grid>
    </TabItem>

How do I save this template so that I can then simply invoke it whenever I want to create a new tab?

If I were to create the layout by code, I would create a function NewTabItem() which would create a new instance of each control, add them to a new TabItem and then add this TabItem to the TabControl, for example (pseudo-code):

void NewTabItem()
{
    Combobox box1 = new Combobox();
    Combobox box2 = new Combobox();
    //... etc
    TabItem tab = new TabItem();
    tab.Add(box1);
    tab.Add(box2);
    tabControl.Add(tab);
}

This way each of the controls is a new instance, and there should be no problem adding any of this to the tabControl. How can I do such a thing using XAML?

Through a ControlTemplate? From what I've seen that's more for controlling the aesthetics of an individual control, not a collection of controls.

Through an ItemsControl? This one I simply can't figure out how to define in XAML and how I would summon a new instance of it to add to the tabControl (or how I would add it to the tabControl, for that matter).

Through some other method? Can this even be done or should I build this layout programatically?

Upvotes: 1

Views: 3267

Answers (1)

lisp
lisp

Reputation: 4198

Define your tab layout in a separate .xaml as a UserControl:

<UserControl x:Class="MyProject.MyTab"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        ...
    </Grid>
</UserControl>

That way you can still easily design it. Adding new tabs is easy.

<TabControl Name="Tabs">
    <TabItem>
        <TabItem.Header>
            <TextBlock>C1</TextBlock>
        </TabItem.Header>
        <local:MyTab/>
    </TabItem>
    <TabItem>
        <TabItem.Header>
            <TextBlock>C2</TextBlock>
        </TabItem.Header>
        <local:MyTab/>
    </TabItem>
</TabControl>

If you choose to add new tabs programmatically, it's just:

var item = new TabItem
{
    Header = "C",
    Content = new MyTab()
};
Tabs.Items.Add(item);

Upvotes: 4

Related Questions