How to put WPF Tab Control tabs on the side - wpf

I am trying to create a Tab Control in WPF that has the tabs arranged down the right side of the control, with the text rotated 90 degrees The look is similar to those plastic tabs you can buy and use in a notebook. I have tried changing the TabStripPlacement to Right, but it just stacks the tabs up on the top right side of the control - not at all what I had in mind.

The effect I believe you are seeking is achieved by providing a HeaderTemplate for the TabItem's in you Tab collection.
<TabControl TabStripPlacement="Right">
<TabControl.Resources>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Padding" Value="4" />
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<ContentPresenter Content="{TemplateBinding Content}">
<ContentPresenter.LayoutTransform>
<RotateTransform Angle="90" />
</ContentPresenter.LayoutTransform>
</ContentPresenter>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
<TabItem Header="Tab Item 1" />
<TabItem Header="Tab Item 2" />
<TabItem Header="Tab Item 3" />
<TabItem Header="Tab Item 4" />
</TabControl>
Hope this helps!

Related

Images and Buttons not filling grid cells WPF XAML

So I have 2 similar problems with the below image. The image is of a UserControl that has been added to a viewbox inside another UserControl:
Image
The button in the top-left does not fill the whole of the grid cell, but the image within it fills the whole button .I have been trying out different methods of binding button images. This is why this is not the same for the other buttons in the grid. However I can't see how they should differ
The black images on the centre top, left, right, and bottom buttons don't fill their buttons. However, when editing the code, the designer shows them filling those buttons. The code for these is identical to the ContentControl above, but has an image path linking to a completely black image instead.
Was wondering if these problems might be related or have a similar fix? I've tried using extra viewboxes and stretch to fill/ alignment parameters but they seem to make no difference.
EDIT:
Implementing Location.xaml in parent UserControl:
<Viewbox Grid.Row="1" Grid.Column="1" Grid.RowSpan="2" Margin="10 10 10 10">
<ContentControl Content="{Binding CurrentLocationViewModel}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type locationViewModel:SmallRoomViewModel}">
<locationView:SmallRoomView/>
</DataTemplate>
<DataTemplate DataType="{x:Type locationViewModel:LargeRoomViewModel}">
<locationView:LargeRoomView/>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</Viewbox>
SmallRoomView.xaml (the UserControl in the image):
<Grid>
<Grid.Resources>
<Button x:Key="wallTile" x:Shared="false" PreviewMouseDown="OnMouseDown" Style="{StaticResource appWallTile}"/>
<Button x:Key="floorTile" x:Shared="false" PreviewMouseDown="OnMouseDown" Style="{StaticResource appFloorTile}"/>
<Button x:Key="doorTile" x:Shared="false" PreviewMouseDown="OnMouseDown" Style="{StaticResource appDoorTile}"/>
</Grid.Resources>
<Button Grid.Row="0" Grid.Column="0" PreviewMouseDown="OnMouseDown">
<Image Stretch="Fill" Source="{Binding tile0_0}"/>
</Button>
<ContentControl Grid.Row="0" Grid.Column="2" Content="{StaticResource doorTile}"/>
<ContentControl Grid.Row="0" Grid.Column="3" Content="{StaticResource wallTile}"/>
...
</Grid>
App.xaml:
<Style x:Key="appDoorTile" TargetType="Button" x:Shared="false">
<Setter Property="Content">
<Setter.Value>
<Image Stretch="Fill" Source="./AllResources/images/tiles/doorTile.png"/>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="appFloorTile" TargetType="Button" x:Shared="false">
<Setter Property="Content">
<Setter.Value>
<Image Stretch="Fill" Source="./AllResources/images/tiles/floors/floorTile.png"/>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="appWallTile" TargetType="Button" x:Shared="false">
<Setter Property="Content">
<Setter.Value>
<Image Stretch="Fill" Source="./AllResources/images/tiles/walls/wallTile.png"/>
</Setter.Value>
</Setter>
</Style>

Resize TabItem header size inside TabControl

I am using MahApps TabControl and i have several TabItems:
<TabControl Name="tabControl" FontSize="12">
<TabItem Header="Statistics" />
</TabControl>
I try to change the font size of the TabControl and TabItems in order to resize my headers but it seems that this not changing anything.
You should use the attached property HeaderFontSize to set the header font size of the tav items.
<TabControl Name="tabControl">
<TabItem Header="Statistics" Controls:ControlsHelper.HeaderFontSize="12" />
</TabControl>
or
<TabControl Name="tabControl">
<TabControl.Resources>
<Style TargetType="{x:Type TabItem}" BasedOn="{StaticResource {x:Type TabItem}}">
<Setter Property="Controls:ControlsHelper.HeaderFontSize" Value="12" />
</Style>
</TabControl.Resources>
<TabItem Header="Statistics" />
</TabControl>
Hope that helps.
In 2.* versions of MahApps.Metro it changes to:
<TabControl Name="tabControl">
<TabItem Header="Statistics" Controls:HeaderedControlHelper.HeaderFontSize="12" />
</TabControl>
or
<TabControl Name="tabControl">
<TabControl.Resources>
<Style TargetType="{x:Type TabItem}" BasedOn="{StaticResource {x:Type TabItem}}">
<Setter Property="Controls:HeaderedControlHelper.HeaderFontSize" Value="12" />
</Style>
</TabControl.Resources>
<TabItem Header="Statistics" />
</TabControl>
Source: https://github.com/MahApps/MahApps.Metro/issues/3711
Documentation is not available at the time of writing.
Put the below code in Window.Resources
<Window
......
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
......
>
<Window.Resources>
<Style x:Key="MenuLevel2" BasedOn="{StaticResource MetroTabItem}" TargetType="{x:Type TabItem}">
<Setter Property="mah:ControlsHelper.HeaderFontSize" Value="15"></Setter>
</Style>
<Window.Resources>
In the TabItem section add the style details.
<TabItem Header="Dimension Alias" Style="{DynamicResource MenuLevel2}">
This worked for me.
since tabItems is a list of item having some common bindings modifying one of Tabitem header height will automatically do for the others
<TabControl>
<TabItem >
<TabItem.Header>
<Label Height="30" Content="Main" FontSize="16" >
</Label>
</TabItem.Header>
</TabItem>
<TabItem Header="Second header" >
<TabItem Header="Third header" >
</TabControl>
In my case this has solved my problem:
<TabControl>
<TabControl.Resources>
<Style TargetType="{x:Type TabItem}" BasedOn="{StaticResource {x:Type TabItem}}">
<Setter Property="Controls:ControlsHelper.HeaderFontSize" Value="12" />
</Style>
</TabControl.Resources>
</TabControl>
Since 2.0 we have to use this in your App.xaml or directly in the resources of your control:
<System:Double x:Key="MahApps.Font.Size.TabItem">16.67</System:Double>

Styles in XAML doesn't work

Why the color of the TabItems is always black? I want black Background and white letters. Also the Button should be white, but it's black too and not visible. There is some conflict but can't find where. Any ideas? Thx in advance for your help.
<UserControl x:Class="Test.Test"
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"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:cal="http://www.caliburnproject.org"
xmlns:cm="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro"
mc:Ignorable="d" d:DesignHeight="252" d:DesignWidth="894" Background="#FF111111">
<Grid>
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Foreground="White" FontSize="48" Margin="70,-14.668,0,0" FontWeight="Light"><Run Language="de-at" Text="test test"/></TextBlock>
<Button x:Name="Close" Content="➔" HorizontalAlignment="Left" VerticalAlignment="Top" Width="58" Foreground="White" Height="58" RenderTransformOrigin="0.5,0.5" FontSize="40" Margin="-7.625,-8,0,0" Padding="1,-5,1,1" Clip="M50.333,8 L-1.667,8 L-1.667,59.843 L50.333,59.843 z" cm:Message.Attach="Close()">
<Button.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleY="1" ScaleX="-1"/>
<SkewTransform AngleY="0" AngleX="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform/>
</TransformGroup>
</Button.RenderTransform>
</Button>
<TabControl Margin="42,52,0,0">
<TabItem Header="Start">
</TabItem>
<TabItem Foreground="White" Header="Start 1" >
</TabItem>
<TabItem Foreground="White" Header="Start 1">
</TabItem>
<TabItem Foreground="White" Header="Start 1">
</TabItem>
<TabItem Foreground="White" Header="Start 1">
</TabItem>
</TabControl>
</Grid>
I tried many things and it didn't work. So what i did is put a TextBlock inside the TabItem.Header:
<TabItem>
<TabItem.Header>
<TextBlock FontSize="25" Text="Start1" />
</TabItem.Header>
</TabItem>
Now I can change the color of the TextBlock with Foreground. But don't know how to change the TextBlock color if I click on the TabItem. Maybe I should open a new topic for that. Thanks all for your contribution.
You're not setting the Background or Foreground properties of your TabControl at all, so it's using the default colors.
The default color of the Background property of any Control object is Brushes.Transparent (source), while the default Foreground property is based on your system colors (source).
You can use an implicit style in your UserControl.Resources to set a property for all objects of the specified type, such as using this style for all Control objects:
<UserControl.Resources>
<Style TargetType="{x:Type Control}">
<Setter Property="Background" Value="Black" />
<Setter Property="Foreground" Value="White" />
</Style>
</UserControl.Resources>
Or if you can add a new Brush to your .Resources and set it's x:Key to the System Key of one of the SystemColors , like this:
<UserControl.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.WindowColorKey}" Color="Black"/>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrush}" Color="White"/>
</UserControl.Resources>
(You might need to test a bit to figure out which is the correct SystemColors Key to use. You can find a list of them here)

HeaderTemplate with multiple items

I'm trying to write a HeaderTemplate for an extender. So far, I've noticed all the examples use the {Binding} keyword to get the data from the header. However, what happens if there are multiple controls within the Header? How do I specify that those controls should be inserted at a specific location?
<Window.Resources>
<Style x:Key="ExpanderStyle" TargetType="{x:Type Expander}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<!-- what do I put in here? -->
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Expander Style="{StaticResource ExpanderStyle}">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock>Some Text</TextBlock>
<TextBlock Text="{Binding SomeBinding}" />
<Button />
</StackPanel>
</Expander.Header>
<Image Source="https://www.google.com/logos/2012/steno12-hp.jpg" />
</Expander>
Should I be moving my binding into the HeaderTemplate in the style and just overwriting whatever the Header in the Expander is?
You can use ContentPresenter to insert whatever the usual content would be into your Template
For example:
<Style x:Key="ExpanderStyle" TargetType="{x:Type Expander}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<Border BorderBrush="Blue" BorderThickness="2">
<ContentPresenter />
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
Header's property Content could contain only one object.
If you merge these object in one panel:
<StackPanel>
<TextBlock>Some Text</TextBlock>
<TextBlock Text="{Binding SomeBinding}" />
<Button />
</StackPanel>
then in template you could use {binding}

Is it possible to Left-Align headers in a WPF TabControl?

Right now, I have a WPF window where all the tab labels of the TabControl are centered.
I'd like the tab levels of the TabControl to be left-aligned.
Is this possible without completely redoing the ControlTemplate?
I tried messing with HorizontalAlignment, HorizontalContentAlignment, etc., but nothing I tried had the desired effect.
If I try this solution (offered by T Levesque):
<TabControl...>
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</TabControl.ItemContainerStyle>
...
</TabControl>
...I get this:
All the tab labels of the TabControl are left-aligned, but the tabs don't stretch properly
Which is close, but it ends up looking kind of like a histogram.
The following will give you the look you are after.
<TabControl TabStripPlacement="Left" HorizontalContentAlignment="Left" >
<TabItem HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Header="Header 1">
<TabItem.Content>Test</TabItem.Content>
</TabItem>
<TabItem HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Header="Header 2" >
<TabItem.Content>Test</TabItem.Content>
</TabItem>
<TabItem HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Header="Header Longer Version">
<TabItem.Content>Test</TabItem.Content>
</TabItem>
</TabControl>
What sort of Control are you using for the TabItem.Header property? If you are simply using a Label, are you specifying the width of the Label to some common value? If the Label is sizing to content then it will appear as you have shown. Try the following with a common width for the labels used to display the header text:
<TabControl TabStripPlacement="Left" >
<TabItem>
<TabItem.Header>
<Label Width="100">test tab 1</Label>
</TabItem.Header>
<TabItem.Content>
xyz
</TabItem.Content>
</TabItem>
<TabItem>
<TabItem.Header>
<Label Width="100">test t2</Label>
</TabItem.Header>
<TabItem.Content>
abc
</TabItem.Content>
</TabItem>
<TabItem>
<TabItem.Header>
<Label Width="100">test tab three</Label>
</TabItem.Header>
<TabItem.Content>
abc
</TabItem.Content>
</TabItem>
</TabControl>
You can define the horizontal alignment for all tab headers :
<TabControl...>
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</TabControl.ItemContainerStyle>
...
</TabControl>
Simply adding the attribute HorizontalContentAlignment="Left" to the TabControl will align tab headers left.
<TabControl
Margin="0,5,0,0"
HorizontalContentAlignment="Left"
TabStripPlacement="Left">
<TabItem
Header="Perform System Administration">
...
<TabItem
Header="Perform Setup Tasks">
...

Resources