3
votes

I have a TabControl in my XAML which is just an empty control as the TabItems are dynamically generated at runtime.

My problem is I want to have the tab title and an image (a "settings" image) in the Header but I'm not sure how to go about this. As I said, I'm generating the TabItems on the fly so how and where would a template to do this fit in and where would I put it etc? Would a TabItem header template apply to TabItem controls created dynamically? (I am assuming/hoping so!)

I've googled and searched around here but no-one quite seems to be doing what I'm doing... just wondering if someone could give me some guidance.

<Grid Name="MainGrid" Background="#333333" ShowGridLines="False" >
    <Grid.RowDefinitions>
        <RowDefinition Height="50"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid Grid.Row="0" ToolTip="Settings">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Column="0" Text="RoboNews" Foreground="SkyBlue" FontSize="32" Padding="5"/>
        <Button Name="btnSettings" Background="Transparent" Grid.Column="1" BorderBrush="#333333" BorderThickness="0" HorizontalAlignment="Right" 
                Click="btnSettings_Click" ToolTip="Click for menu">
            <!--<Image Source="Images/Settings48x48.png"/>-->
            <Image Source="/Images/MenuOpen.png" Width="36" />
        </Button>

    </Grid>

    <TabControl Name="tabCategories" Grid.Row="1" Background="Black" SelectionChanged="tabCategories_SelectionChanged">  

    </TabControl>
</Grid>
1
You want the tab title and an image for each TabItem you have created?stukselbax
stukselbax, yes that's correct... just not sure how to create the template or where to put it or if the dynamically created TabItem will pick it up and use it.nzmike

1 Answers

2
votes

You can create a UserControl for your header

<UserControl DataContext="{Binding RelativeSource={RelativeSource Self}}" x:Class="TabControlHeader.TabItemHeader"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" Width="Auto" Height="Auto">
    <Grid >
        <StackPanel>
            <Image Source="{Binding ImageSource}"></Image>
            <TextBlock Text="{Binding Text}"></TextBlock>
        </StackPanel>
    </Grid>
</UserControl>

With ideally DPs defined in its ViewModel, but for the time being, in code behind:

public string ImageSource
{
    get { return (string)GetValue(ImageSourceProperty); }
    set { SetValue(ImageSourceProperty, value); }
}

// Using a DependencyProperty as the backing store for ImageSource.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty ImageSourceProperty =
    DependencyProperty.Register("ImageSource", typeof(string), typeof(TabItemHeader));



public string Text
{
    get { return (string)GetValue(TextProperty); }
    set { SetValue(TextProperty, value); }
}

// Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty TextProperty =
    DependencyProperty.Register("Text", typeof(string), typeof(TabItemHeader));

Then while creating your TabItem you need to set its HeaderTemplate:

TabItem tabItem = new TabItem();
tabItem.Height = 100;
tabItem.Width = 50;
var header = new FrameworkElementFactory(typeof(TabItemHeader));
header.SetValue(TabItemHeader.TextProperty, "This is Text");
header.SetValue(TabItemHeader.ImageSourceProperty, "This is Image uri");
header.SetValue(TabItemHeader.HeightProperty, (double)50);
header.SetValue(TabItemHeader.WidthProperty, (double)50);


tabItem.HeaderTemplate = new DataTemplate { VisualTree = header };            
tabCategories.Items.Add(tabItem);