Mahapps.metro: help to add an icon to the TabControl

Created on 26 Mar 2013  路  11Comments  路  Source: MahApps/MahApps.Metro

Hi all!
I'm trying without results to add an icon or on the left of the text or on top..
does anybody can help me?

thanks in advance!

Most helpful comment

Thanks a lot header template works. For future visitors:

<TabItem.HeaderTemplate>
    <DataTemplate>
        <DockPanel LastChildFill="True">
            <Rectangle DockPanel.Dock="Left" Width="20" Height="20" Fill="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}, Path=(TextElement.Foreground)}" >
                <Rectangle.OpacityMask>
                    <VisualBrush Stretch="Fill" Visual="{StaticResource appbar_adobe_acrobat}" />
                </Rectangle.OpacityMask>
            </Rectangle>
            <Label Padding="0"
                    Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}, Path=(TextElement.Foreground)}"
                    FontSize="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}, Path=(TextElement.FontSize)}"
                    >
                Test
            </Label>
        </DockPanel>
    </DataTemplate>
</TabItem.HeaderTemplate>

All 11 comments

Something like this?
image

The control template for the TabItem is a Label with a contentpresenter. A Label is by itself a content control, so you can basically set the header to what ever you want, even without overriding the control template.

The picture above is from the demo project that comes with MahApps.Metro. There are only minor adjustments needed to include a picture in a TabItem:

           <TabItem>
                <TabItem.Header>
                    <DockPanel LastChildFill="True">
                        <Controls:MetroImage DockPanel.Dock="Left" 
                            Source="{StaticResource appbar_chess_bishop}" 
                            Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type Label}}, Path=Foreground}" 
                            Height="16" Width="16" Margin="2,0"/>
                        <Label Padding="0"
                            Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type Label}}, Path=Foreground}"
                            FontSize="{Binding RelativeSource={RelativeSource AncestorType={x:Type Label}}, Path=FontSize}"
                            >
                            _More Controls Here!
                        </Label>
                    </DockPanel>
                </TabItem.Header>                    

The RelativeSource bindings are there to keep the hoover effect and color difference between selected and non selected items.

wow!
thanks vegar!!! :+1:
and just a little question...
if I have my source in the resource: for example if I need to use it in an image I set as source this:

Source="/myProject;component/Resources/Gears.png"

but gives error:

Additional information: the settings of the property 'MahApps.Metro.Controls.MetroImage.Source' gives an exception.

The Source property of the MetroImage component is a Visual, which is nice if you want to use one of the bundled icons. For a png, just use a regular image component instead.

thanks again vegar, with the image works, but I lose the foreground property, so the icon didn't change color like the bundled icons...

is better try to convert my personal icons to StaticResource _(how can I do this?)_ or try to create my personal image derived class that manages the foreground property like MetroImage?

thanks

This has nothing to do with the keyword StaticResource.

A png image is a bitmap where all the pixels comes with its own color.
The bundled icons are vector graphics without any color information at all. It only knows how to draw itself with whatever foreground color that is selected.

You should always prefer vector over bitmap for many reasons, like size and scaleability, but not all images can easily be represented as a vector graphic.

If you want to show the image different when the tab is selected or not, you could play with other parameters. You can set the opacity to make the bitmap semi-transparent when it's not selected, or you can play with different bitmap effects. Or you could toggle between two different bitmaps.

I'm afraid, though, that you soon will need to either override the style/control template or at least use a value converter to effectively archive this. On the other hand, neither value converters nor control templates are that hard to make, so just go for it. And remember: Use the Source, Luke! :-)

ok, I've found a quick solution: I created my own icon.xaml like this:

<ResourceDictionary xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <Image x:Key="Gears_On" Source="Gears_128.png"/>
</ResourceDictionary>

and in my code I use

Source="{StaticResource Gears_On}"

and works fine!!

last thing after I hope to be ok :)

I have a tabcontrol under another tabcontrol:
if I use a MahApps standard TabControl everything is ok, but using your code posted above, the hover and selected is not correct starting from the second level

thanks again

That was strange. I have no idea of why. Tried to look at it in WPF Insepctor, and suddenly it corrected it self. Closed the demo application and tried again, but this time it stayed broken.

Strange.

I think I would start experimenting with a second styling of the TabItem. You can base it on the existing one and just change the control template. Start by copying the control template already defined, and replace the label with what ever you want. You will see that the label is named "root" and that this name is referred by the triggers giving the hoover/selected effect. You will need to change this so that the triggers update whatever you put there instead.

You will have to find a way of binding the image for each tab to something so that you don't need to specify one style per tab, though...

very strange, if I open WPF inspector it works fine, otherwise broken.
I've tried also to create a separate usercontrols, but the problem is still active...

I've tried also simpy to derive a style and rename root as root2, _(WPF inspector tell me that is ok)_, but the problem is still persistent... seems something like a 'refresh' situation

Hello,

It seems this solution doesn't work anymore. I checked the control template for TabItem and the label is changed to a contentpresenter. Therefore the binding expression can't find an ancestor. After I changed the binding expression for content presenter everything seems fine until i click the tabItem to select, when clicked the text and the image disappeares. Here is what i wrote inside the mahapss demo project:

Tab Item Header:

<TabItem>
    <TabItem.Header>
        <DockPanel LastChildFill="True">
            <Rectangle DockPanel.Dock="Left" Width="20" Height="20" Fill="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}, Path=(TextElement.Foreground)}" >
                <Rectangle.OpacityMask>
                    <VisualBrush Stretch="Fill" Visual="{StaticResource appbar_adobe_acrobat}" />
                </Rectangle.OpacityMask>
            </Rectangle>
            <Label Padding="0"
            Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}, Path=(TextElement.Foreground)}"
            FontSize="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}, Path=(TextElement.FontSize)}"
            >
                Test
            </Label>
        </DockPanel>
    </TabItem.Header>
    <exampleViews:TextExamples DataContext="{Binding}" />
</TabItem>

Tab Item Header

If anybody could solve the dissappearing issue it would be really helpful =)

I think you should try the HeaderTemplate instead Header.

Thanks a lot header template works. For future visitors:

<TabItem.HeaderTemplate>
    <DataTemplate>
        <DockPanel LastChildFill="True">
            <Rectangle DockPanel.Dock="Left" Width="20" Height="20" Fill="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}, Path=(TextElement.Foreground)}" >
                <Rectangle.OpacityMask>
                    <VisualBrush Stretch="Fill" Visual="{StaticResource appbar_adobe_acrobat}" />
                </Rectangle.OpacityMask>
            </Rectangle>
            <Label Padding="0"
                    Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}, Path=(TextElement.Foreground)}"
                    FontSize="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}, Path=(TextElement.FontSize)}"
                    >
                Test
            </Label>
        </DockPanel>
    </DataTemplate>
</TabItem.HeaderTemplate>
Was this page helpful?
0 / 5 - 0 ratings

Related issues

fredericoregateiro picture fredericoregateiro  路  10Comments

SteffanDonal picture SteffanDonal  路  11Comments

seb30 picture seb30  路  12Comments

StickNitro picture StickNitro  路  11Comments

kshkrao3 picture kshkrao3  路  12Comments