#899 – Displaying Multiple Controls on a TabControl’s Tabs

You can display simple text on the clickable tabs of a TabControl by setting the Header property of each TabItem to some text.  You can also set the Header to any single control, for example an Image control.

If you want to display something more complex than either some text or a single control, you can set the Header property to contain a layout panel that in turn contains other controls.

    <TabControl Margin="10">
        <TabItem>
            <TabItem.Header>
                <StackPanel>
                    <Image Source="Augustus.jpg" Height="60" Margin="5"/>
                    <TextBlock Text="Augustus" HorizontalAlignment="Center"/>
                </StackPanel>
            </TabItem.Header>
            <TextBlock Text="Augustus stuff goes here.." Margin="10"/>
        </TabItem>
        <TabItem>
            <TabItem.Header>
                <StackPanel>
                    <Image Source="Tiberius.jpg" Height="60" Margin="5"/>
                    <TextBlock Text="Tiberius" HorizontalAlignment="Center"/>
                </StackPanel>
            </TabItem.Header>
            <TextBlock Text="Tiberius stuff goes here.." Margin="10"/>
        </TabItem>
        <TabItem>
            <TabItem.Header>
                <StackPanel>
                    <Image Source="Caligula.jpeg" Height="60" Margin="5"/>
                    <TextBlock Text="Caligula" HorizontalAlignment="Center"/>
                </StackPanel>
            </TabItem.Header>
            <TextBlock Text="Caligula stuff goes here.." Margin="10"/>
        </TabItem>
    </TabControl>

899-001

Advertisement

#898 – Setting the Text that Appears on a TabItem

Each tab within a TabControl is represented by an instance of a TabItem.  If you want some text to be displayed on the clickable portion of a tab, you can specify the text that should appear by setting the Header property of the TabItem.

    <TabControl Margin="10" >
        <TabItem Header="Augustus">
            <StackPanel Orientation="Horizontal">
                <Image Source="Augustus.jpg" Height="100" Margin="5"/>
                <TextBlock Text="Augustus" VerticalAlignment="Center"/>
            </StackPanel>
        </TabItem>
        <TabItem Header="Tiberius">
            <StackPanel Orientation="Horizontal">
                <Image Source="Tiberius.jpg" Height="100" Margin="5"/>
                <TextBlock Text="Tiberius" VerticalAlignment="Center"/>
            </StackPanel>
        </TabItem>
    </TabControl>

898-001

#893 – Creating a GroupBox with a Border But No Header

There are cases where you might want a GroupBox for grouping a set of child controls, but without the associated header text.  If you try just omitting the Header, but you’ll see a little gap at the top of the GroupBox.

893-001

To remove the gap you could just use a Border element instead of a GroupBox, changing its style to match the GroupBox.  You can also edit the default style of the GroupBox.

To edit the style of the GroupBox, start by right-clicking the GroupBox control in Visual Studio and select Edit TemplateEdit a Copy.

893-002

Accept the default name for the style.

893-003

Within the Style element, find the OpacityMask, near the bottom, and comment it out.

894-004

Note that your GroupBox element is now using your modified copy of the style.

    <GroupBox Margin="10" BorderBrush="DarkGray"
              Style="{DynamicResource GroupBoxStyle1}">

The GroupBox will no longer have the little gap where the header should go.
893-005

#834 – Displaying Custom Content on a TabControl’s Tabs

When you use a TabControl in your application, each tab is represented by a TabItem.  The content of the TabItem is a single container and items placed within this container show up in the body of the TabControl when that tab is clicked.

When you set the Header property of a TabItem to some text, that text will be drawn on the tab.

    <TabControl Margin="5" >
        <TabItem Header="His">
            <StackPanel>
                <Label Content="His stuff goes here"/>
            </StackPanel>
        </TabItem>

        <TabItem Header="Hers">
            <StackPanel>
                <Label Content="Her stuff goes here"/>
            </StackPanel>
        </TabItem>
    </TabControl>

834-001
Because TabItem.Header is of type object, you can set the Header to anything that you like.  (E.g. a panel containing multiple items).

    <TabControl Margin="5" >
        <TabItem>
            <TabItem.Header>
                <Image Source="His.png" Height="50"/>
            </TabItem.Header>
            <StackPanel>
                <Label Content="His stuff goes here"/>
            </StackPanel>
        </TabItem>

        <TabItem>
            <TabItem.Header>
                <Image Source="Hers.png" Height="50"/>
            </TabItem.Header>
            <StackPanel>
                <Label Content="Her stuff goes here"/>
            </StackPanel>
        </TabItem>
    </TabControl>

834-002

#510 – The Header of an Expander Can Be Anything

The Header property of an Expander control doesn’t have to be a string.  You can set it to any object and that object will be displayed at the top of the Expander, whether the Expander is collapsed or expanded.

In the example below, we use an Image for the header of the Expander and then a GroupBox for its content.

        <Expander Margin="10" >
            <Expander.Header>
                <Image Source="Images/CptBlood-1935.png" Width="51" Height="72"/>
            </Expander.Header>
            <GroupBox Header="More Info">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>

                    <Label Grid.Row="0" Grid.Column="0" Content="Title" FontWeight="Bold" HorizontalAlignment="Right"/>
                    <Label Grid.Row="0" Grid.Column="1" Content="Captain Blood"/>

                    <Label Grid.Row="1" Grid.Column="0" Content="Year" FontWeight="Bold" HorizontalAlignment="Right"/>
                    <Label Grid.Row="1" Grid.Column="1" Content="1935"/>

                    <Label Grid.Row="2" Grid.Column="0" Content="Director" FontWeight="Bold" HorizontalAlignment="Right"/>
                    <Label Grid.Row="2" Grid.Column="1" Content="Michael Curtiz"/>

                    <Label Grid.Row="3" Grid.Column="0" Content="Star" FontWeight="Bold" HorizontalAlignment="Right"/>
                    <Label Grid.Row="3" Grid.Column="1" Content="Errol Flynn"/>
                </Grid>
            </GroupBox>
        </Expander>

The Expander starts out collapsed:

Then shows GroupBox when expanded:

#505 – The Header of a GroupBox Can Be Anything

The Header property of a GroupBox control specifies the content to be displayed along the top border of the GroupBox.  This is often a text string, specified in XAML.  But similar to the Content property of a content control, the Header property can be set to any object.

In the example below, Header is set to a Label, which then allows more control over how the Label will appear than if just a text string had been used.

    <GroupBox Margin="15">
        <GroupBox.Header>
            <Label FontWeight="Bold" FontFamily="Georgia" FontSize="16"  Content="Dog Info"/>
        </GroupBox.Header>
        <Grid Margin="10">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>

            <Label Grid.Row="0" Grid.Column="0" Content="Name:" FontWeight="Bold" HorizontalAlignment="Right"/>
            <Label Grid.Row="0" Grid.Column="1" Content="Kirby"/>
            <Label Grid.Row="1" Grid.Column="0" Content="Age:" FontWeight="Bold" HorizontalAlignment="Right"/>
            <Label Grid.Row="1" Grid.Column="1" Content="15" />
            <Label Grid.Row="2" Grid.Column="0" Content="Hobby:" FontWeight="Bold" HorizontalAlignment="Right"/>
            <Label Grid.Row="2" Grid.Column="1" Content="Chasing balls"/>
        </Grid>
    </GroupBox>

#346 – No Need to Set Header Property for MenuItem When Using Commands

If you use one of the preexisting RoutedUICommand objects for a WPF command, e.g. ApplicationCommands.Open, you’ll notice that the RoutedUICommand instance has a Text property.  This property in the command is used to set the label appearing on any MenuItem instances that have attached to the command by setting their Command property.  You don’t need to set the menu item’s Header property explicitly.

    <Window.ContextMenu>
        <ContextMenu>
            <MenuItem Command="ApplicationCommands.Open"/>
            <MenuItem Command="ApplicationCommands.Close"/>
            <MenuItem Command="ApplicationCommands.New"/>
        </ContextMenu>
    </Window.ContextMenu>


Notice that the text for each menu item is automatically filled in, since the text strings are defined in the RoutedUICommand object.  Also notice that some of the commands also define key gestures (e.g. Ctrl+O) for executing the command.