WPF ControlTemplate Trigger - wpf

All,
I am trying to set up a Template for a Window. What I want is to change the margin and the border thickness depending upon the state of the window. I am trying to do it using Trigger, but when I run the application, triggers don't fire. My question is, how can I make the triggers fire when the window state is changed?
The XAML I have is (I have removed most of the code to keep the posting simple):
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1" Background="#FFE8E8E8"
Style="{DynamicResource ChromeWindowStyle}"
mc:Ignorable="d"
Title="BaseWindow" Width="500" Height="300">
<WindowChrome.WindowChrome>
<WindowChrome ResizeBorderThickness="6" CaptionHeight="0" GlassFrameThickness="0" />
</WindowChrome.WindowChrome>
<Window.Resources>
<Style x:Key="ChromeWindowStyle" TargetType="{x:Type Window}">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Background" Value="#FFE8E8E8"/>
<Setter Property="WindowStyle" Value="None" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border x:Name="MainBorder" Background="White" BorderBrush="Gray" BorderThickness="1">
<DockPanel LastChildFill="True">
<Border Height="30" DockPanel.Dock="Top">
<DockPanel LastChildFill="False">
<TextBlock Text="Heading" DockPanel.Dock="Left" VerticalAlignment="Center" />
<Button x:Name="CloseButton" Content="Close" DockPanel.Dock="Right" />
<Button x:Name="MaximizeButton" Content="Max" DockPanel.Dock="Right" />
<Button x:Name="MinButton" Content="Min" DockPanel.Dock="Right"/>
</DockPanel>
</Border>
<AdornerDecorator DockPanel.Dock="Bottom">
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"/>
</AdornerDecorator>
</DockPanel>
</Border>
<!--This piece wont trigger - start -->
<ControlTemplate.Triggers>
<Trigger Property="WindowState" Value="Normal">
<Setter Property="Margin" Value="8" />
<Setter Property="BorderThickness" Value="1" />
</Trigger>
<Trigger Property="WindowState" Value="Maximized">
<Setter Property="Margin" Value="8" />
<Setter Property="BorderThickness" Value="0" />
</Trigger>
</ControlTemplate.Triggers>
<!--This piece wont trigger - end -->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
</Grid>
</Window>

Your ControlTemplate.Triggers are trying to set properties on the ControlTemplate itself, which in-and-of itself is not a visual element. They need to explicitly specify the name of the Border control:
<ControlTemplate.Triggers>
<Trigger Property="WindowState" Value="Normal">
<Setter TargetName="MainBorder" Property="Margin" Value="8" />
<Setter TargetName="MainBorder" Property="BorderThickness" Value="1" />
</Trigger>
<Trigger Property="WindowState" Value="Maximized">
<Setter TargetName="MainBorder" Property="Margin" Value="8" />
<Setter TargetName="MainBorder" Property="BorderThickness" Value="0" />
</Trigger>
</ControlTemplate.Triggers>
EDIT: Oh ok, I'm still on 4.5.1, maybe that's new behavior? In that case I'd go the other way i.e. put DataTriggers on the border control itself:
<Style x:Key="ChromeWindowStyle" TargetType="{x:Type Window}">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="WindowStyle" Value="None" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border BorderBrush="Gray">
<Border.Style>
<Style TargetType="{x:Type Border}">
<Setter Property="Margin" Value="8" />
<Setter Property="BorderThickness" Value="1" />
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=WindowState}" Value="Maximized">
<Setter Property="Margin" Value="8" />
<Setter Property="BorderThickness" Value="0" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<DockPanel LastChildFill="True">
<Border Height="30" DockPanel.Dock="Top">
<DockPanel LastChildFill="False">
<TextBlock Text="Heading" DockPanel.Dock="Left" VerticalAlignment="Center" />
<Button x:Name="CloseButton" Content="Close" DockPanel.Dock="Right" />
<Button x:Name="MaximizeButton" Content="Max" DockPanel.Dock="Right" Click="MaximizeButton_Click"/>
<Button x:Name="MinButton" Content="Min" DockPanel.Dock="Right"/>
</DockPanel>
</Border>
<AdornerDecorator DockPanel.Dock="Bottom">
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"/>
</AdornerDecorator>
</DockPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Related

How to override general style with trigger in ControlTemplate?

I have a TabControl that displays a different Tab header foreground and background for a selected tab. But I would like to set a general foreground color for TextBlocks within the tab item content control. What is happening instead is all the headers are getting the general TextBlock foreground color and the tab control is not changing the foreground color for the header when the tab is selected.
So in my main window I have:
<Grid>
<TabControl Style="{StaticResource TabControlStyle}">
<TabItem Header="Tab 1" IsSelected="True">
<TextBlock Text="Text in Tab 1"/>
</TabItem>
<TabItem Header="Tab 2">
<TextBlock Text="Text in Tab 2"/>
</TabItem>
</TabControl>
</Grid>
and in my resource file I have defined my colors and content templates:
<Color x:Key="DarkGray">#404040</Color>
<Color x:Key="DarkGreen">#3A5038</Color>
<Color x:Key="ForegroundColor">#FFF1F1F1</Color>
<SolidColorBrush x:Key="DarkGrayBrush"
Color="{StaticResource DarkGray}" />
<SolidColorBrush x:Key="ForegroundColorBrush"
Color="{StaticResource ForegroundColor}" />
<SolidColorBrush x:Key="DarkGreenBrush"
Color="{StaticResource DarkGreen}" />
<Style TargetType="TextBlock">
<Setter Property="Foreground"
Value="{StaticResource DarkGrayBrush}" />
</Style>
<Style x:Key="TabControlStyle"
TargetType="TabControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabControl">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TabPanel Grid.Row="0"
Background="{TemplateBinding Background}"
IsItemsHost="true" />
<ContentPresenter Grid.Row="1"
ContentSource="SelectedContent" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Resources>
<Style TargetType="TabItem">
<Setter Property="BorderThickness"
Value="0" />
<Setter Property="FontSize"
Value="16" />
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<Border>
<ContentPresenter Content="{TemplateBinding Content}" />
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Border Name="Border"
Width="145"
Margin="10"
Padding="0"
BorderThickness="0"
CornerRadius="20">
<ContentPresenter x:Name="ContentSite"
Margin="10"
HorizontalAlignment="Center"
VerticalAlignment="Center"
ContentSource="Header" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected"
Value="True">
<Setter TargetName="Border"
Property="Background"
Value="{StaticResource DarkGreenBrush}" />
<Setter Property="Foreground"
Value="{StaticResource ForegroundColorBrush}" />
</Trigger>
<Trigger Property="IsSelected"
Value="False">
<Setter Property="Foreground"
Value="{StaticResource DarkGrayBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
</Style>
I am targeting .NET 4.5 on a Windows 10 operating system.
Thanks, Will
Set the TextBlock.Foreground property of the ContentPresenter:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Border Name="Border"
Width="145"
Margin="10"
Padding="0"
BorderThickness="0"
CornerRadius="20">
<ContentPresenter x:Name="ContentSite"
Margin="10"
HorizontalAlignment="Center"
VerticalAlignment="Center"
ContentSource="Header" TextBlock.Foreground="{StaticResource DarkGrayBrush}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border"
Property="Background"
Value="{StaticResource DarkGreenBrush}" />
<Setter TargetName="ContentSite" Property="TextBlock.Foreground"
Value="{StaticResource ForegroundColorBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>

WPF - Is it possible to create a shared base window class, that is both chromeless and resizable?

I can create a standard WPF window as follows, and all works fine.
<Window x:Class="WpfWindowStyleTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
AllowsTransparency="True"
Background="Transparent"
ResizeMode="CanResizeWithGrip"
SizeToContent="WidthAndHeight"
TextOptions.TextFormattingMode="Display"
TextOptions.TextRenderingMode="ClearType"
Topmost="True"
UseLayoutRounding="True"
WindowStyle="None">
<Grid>
<Border Background="LightGreen"
BorderBrush="Navy"
BorderThickness="2"
CornerRadius="4">
// window content here ...
</Border>
</Grid>
</Window>
However, my application requires a number of common components (way beyond a simple border) to be shared by all windows, so I tried to extract it into a common class.
public class BaseView: Window
{
static BaseView()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(BaseView), new FrameworkPropertyMetadata(typeof(BaseView)));
}
}
with the following style in generic.xaml
<Style BasedOn="{StaticResource {x:Type Window}}" TargetType="{x:Type local:BaseView}">
<Setter Property="AllowsTransparency" Value="True" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="SizeToContent" Value="WidthAndHeight" />
<Setter Property="TextOptions.TextFormattingMode" Value="Display" />
<Setter Property="TextOptions.TextRenderingMode" Value="ClearType" />
<Setter Property="Topmost" Value="True" />
<Setter Property="UseLayoutRounding" Value="True" />
<Setter Property="WindowStyle" Value="None" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:BaseView}">
<Grid>
<AdornerDecorator>
<Border Background="LightGreen"
BorderBrush="Navy"
BorderThickness="2"
CornerRadius="4">
<ContentPresenter Margin="24" HorizontalAlignment="Left" />
</Border>
</AdornerDecorator>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This works fine.
However, when I add another property setter to the style
<Setter Property="ResizeMode" Value="CanResizeWithGrip" />
The whole control template is ignored, and just the specified window content is displayed (in an empty, resizable window).
Is there any way around this?
Your issue depends on the standard Window style; take a look:
<Style x:Key="{x:Type Window}" TargetType="{x:Type Window}">
<Setter Property="Control.Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
<Setter Property="Control.Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" />
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border Background="{TemplateBinding Control.Background}" BorderBrush="{TemplateBinding Control.BorderBrush}" BorderThickness="{TemplateBinding Control.BorderThickness}">
<AdornerDecorator>
<ContentPresenter />
</AdornerDecorator>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Window.ResizeMode" Value="CanResizeWithGrip">
<Setter Property="Control.Template" Value="{StaticResource ħ}" />
</Trigger>
</Style.Triggers>
</Style>
As you can see, if the ResizeMode is set to CanResizeWithGrip, a trigger changes the Window's template.
A simple solution could be adding a ResizeGrip to your template and avoing that your style inherits from the default one. Something like:
<Style TargetType="{x:Type local:BaseView}">
<Setter Property="AllowsTransparency" Value="True" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="SizeToContent" Value="WidthAndHeight" />
<Setter Property="TextOptions.TextFormattingMode" Value="Display" />
<Setter Property="TextOptions.TextRenderingMode" Value="ClearType" />
<Setter Property="Topmost" Value="True" />
<Setter Property="UseLayoutRounding" Value="True" />
<Setter Property="WindowStyle" Value="None" />
<Setter Property="ResizeMode" Value="CanResizeWithGrip" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:BaseView}">
<Grid>
<AdornerDecorator>
<Border Background="LightGreen"
BorderBrush="Navy"
BorderThickness="2"
CornerRadius="4">
<ContentPresenter Margin="24" HorizontalAlignment="Left" />
</Border>
</AdornerDecorator>
<ResizeGrip Name="WindowResizeGrip" HorizontalAlignment="Right" VerticalAlignment="Bottom" IsTabStop="False" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I hope it can help you.

Two buttons with TextBox in the middle, ControlTemplate

Having a problem with this style, I can't find a way to make the following layout:
So I need just the corners of the buttons on the outside to be rounded, but I don't know how to do this, as the ControlTemplate for the buttons can't have the CornerRadius property as I would have to round all the corners.
This is the style I have got now, it just produces the style as seen above but with no CornerRadius.
P.S. There does seem to be an issue with the far left button going behind the TextBox which I noticed when the TextBox was slightly transparent. Not sure what is causing this!
XAML
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Controls">
<Style TargetType="{x:Type local:NumericUpDown}">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="HorizontalContentAlignment" Value="Right" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Focusable" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:NumericUpDown}">
<ControlTemplate.Resources>
<Style TargetType="Button">
<Setter Property="Padding" Value="5" />
<Setter Property="Background" Value="#434953" />
<Setter Property="MinWidth" Value="30" />
<Setter Property="MinHeight" Value="25" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" ClipToBounds="True">
<Border x:Name="Border1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="#434953">
<ContentPresenter Content="{Binding Path=Content, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border1" Property="Background" Value="#834953"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ControlTemplate.Resources>
<Border Focusable="{TemplateBinding Focusable}">
<DockPanel Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
VerticalAlignment="Center"
Focusable="False">
<Button x:Name="PART_DecreaseButton" DockPanel.Dock="Left">
<Button.Content>
<Path Data="M0,0 L1,0 0.5,1Z"
Fill="White"
Width="8"
Height="6"
Stretch="Fill"/>
</Button.Content>
</Button>
<Button x:Name="PART_IncreaseButton" DockPanel.Dock="Right">
<Button.Content>
<Path Data="M0,1 L1,1 0.5,0Z"
Width="8"
Height="6"
Fill="White"
Stretch="Fill" />
</Button.Content>
</Button>
<TextBox x:Name="PART_TextBox"
Foreground="White"
HorizontalContentAlignment="Center"
HorizontalAlignment="Stretch"
Background="#22252b"
BorderThickness="0"
MinWidth="35" IsEnabled="True" Focusable="False" />
</DockPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True" SourceName="PART_DecreaseButton">
<Setter Property="Background" Value="Red" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
you can encapsulate the whole thing and apply opacity mask like in this tutorial
http://wpf.2000things.com/2012/05/11/556-clipping-to-a-border-using-an-opacity-mask/

Changing the text color of the selected tabItem in a TabControl?

In the second code there is a textBlock with the text "Mina övningar"
How can I change the text color to black when the tabItem is selected?
style:
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border Name="Border" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" Margin="0,0,0,13" CornerRadius="5" >
<ContentPresenter x:Name="ContentSite" VerticalAlignment="Top" HorizontalAlignment="Center" ContentSource="Header" Margin="9"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Black"/>
<Setter TargetName="Border" Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFF9F7FD" Offset="0.432" />
<GradientStop Color="#FFECF7FD" Offset="0.433" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter TargetName="ContentSite" Property="Margin" Value="9,12,9,9" />
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Border" Property="Background" Value="Transparent" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
tabitem:
<TabItem Background="White">
<TabItem.Header>
<StackPanel Orientation="Vertical">
<Image Height="32" Source="/Glosboken;component/Images/library bookmarked.png" />
<TextBlock Text="Mina övningar" Margin="0,0,0,0" VerticalAlignment="Center" Foreground="White" />
</StackPanel>
</TabItem.Header>
<Grid>
<ListBox Height="216" Name="bookslist" VerticalAlignment="Top" Background="White" BorderBrush="White" Foreground="White" SelectedIndex="0" Margin="0,0,129,0" />
</Grid>
</TabItem>
One solution is to use a separate style for this situation:
<Style x:Key="TabItemText" TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=TabItem}}" Value="True">
<Setter Property="Foreground" Value="Black"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=TabItem}}" Value="False">
<Setter Property="Foreground" Value="White"/>
</DataTrigger>
</Style.Triggers>
</Style>
and then replace:
Foreground="White"
with:
Style="{StaticResource TabItemText}"
in the TextBlock.
I did this by naming the ContentPresenter and targeting it in the trigger.
This way it keeps everything for the TabItem style in one place.
Complete Example:
<Window x:Class="TabControlText.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="TabItemStyle1" TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Border x:Name="Border" BorderThickness="1,1,1,0" CornerRadius="5,5,0,0"
Padding="25,5,25,5" Margin="0,0,0,0" BorderBrush="Gainsboro">
<ContentPresenter x:Name="ContentSite" ContentSource="Header" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="TextElement.Foreground" TargetName="ContentSite" Value="White"/>
<Setter TargetName="Border" Property="Background" Value="Black"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter Property="TextElement.Foreground" TargetName="ContentSite" Value="Black"/>
<Setter TargetName="Border" Property="Background" Value="White" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<TabControl>
<TabItem Header="Tab 1" Style="{DynamicResource TabItemStyle1}" />
<TabItem Header="Tab 2" Style="{DynamicResource TabItemStyle1}" />
<TabItem Header="Tab 3" Style="{DynamicResource TabItemStyle1}" />
<TabItem Header="Tab 4" Style="{DynamicResource TabItemStyle1}" />
</TabControl>
</Grid>
I extended Scott Solmer's great code by making it a resource dictionary because I needed this TabItem styling application wide.
So add new TabItemStyles.xaml under the Resources Dictionary folder which was called "Resources" :
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="ColoredTabsStyle" TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Border x:Name="Border" BorderThickness="1,1,1,0" CornerRadius="5,5,0,0"
Padding="25,5,25,5" Margin="0,0,0,0" BorderBrush="Gainsboro">
<ContentPresenter x:Name="ContentSite" ContentSource="Header" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="TextElement.Foreground" TargetName="ContentSite" Value="White" />
<Setter TargetName="Border" Property="Background" Value="Black" />
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter Property="TextElement.Foreground" TargetName="ContentSite" Value="Black" />
<Setter TargetName="Border" Property="Background" Value="White" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I changed my app.xaml to know about the new resource dictionary. WARNING - adjust the source and component locations for your application:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/TruPredict;component/Resources/TabItemStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
Then I used style in the actual screen everywhere in the application I needed. Unlike Scott, I prefer using StaticResource rather than DynamicResource unless I have to.:
<TabControl>
<TabItem Header="Tab1" Style="{StaticResource ColoredTabsStyle}">
<TabItem Header="Tab2" Style="{StaticResource ColoredTabsStyle}">
<TabItem Header="Tab3" Style="{StaticResource ColoredTabsStyle}">
<TabControl>

How can I access to an object in a control of wpf, programmatically?

<TabControl x:Class="MyTabControl.Tab_Control"
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:local="clr-namespace:MyTabControl" Padding="0" Background="White" BorderBrush="Black" Loaded="TabControl_Loaded">
<TabControl.Resources>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid Name="Grid_Main">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border Grid.Column="1" Name="border_Main" Background="#F0F0F0" BorderBrush="LightGray" BorderThickness="1,1,1,0" CornerRadius="4,4,0,0"
Margin="-2,0,2,0" SnapsToDevicePixels="True" >
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="13" HorizontalAlignment="Center" Name="TextBlock"
Foreground="DarkGray">
<ContentPresenter x:Name="ContentSite" VerticalAlignment="Center"
HorizontalAlignment="Center" ContentSource="Header" Margin="5,2,5,2"/></TextBlock>
</StackPanel>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="border_Main" Property="Background" Value="White" />
<Setter TargetName="border_Main" Property="BorderBrush" Value="Gray" />
<Setter TargetName="TextBlock" Property="Foreground" Value="Black" />
<Setter TargetName="border_Main" Property="Margin" Value="-2,0,2,-1" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True" SourceName="border_Main" >
<Setter TargetName="border_Main" Property="Background" Value="White" />
<Setter TargetName="border_Main" Property="BorderBrush" Value="DarkGray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
</TabControl>
How can I access my "border_Main" control programmatically?
I would recommend using LinqToVisualTree ...
http://www.scottlogic.co.uk/blog/colin/2010/03/linq-to-visual-tree/
You can find all the "border_Main" controls within the TabControl as follows:
tabControl.Descendants<Border>().Where(d => d.Name=="border_Main");
Or, if you could use the above query on a TabItem directly if you want to find a single border_Main instance.

Resources