Moving items down when adding error info using INotifyDataErrorInfo - wpf

I have for example a combobox and if it is not chosen then I am displaying an error message under it.
When the message is displayed it is displayed on top of the control that is under the combobox.
Is there a way to move the control(s) under the combobox down when the error message is shown?
<UserControl.Resources>
<Style x:Key="ErrorStackPanel" TargetType="{x:Type StackPanel}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Margin" Value="0 20 0 5"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="ErrorComboBox" TargetType="{x:Type ComboBox}">
<Setter Property="MinWidth" Value="180" />
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<StackPanel Orientation="Vertical" SnapsToDevicePixels="True">
<!--Placeholder for the TextBox itself-->
<AdornedElementPlaceholder x:Name="textBox" />
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ErrorContent}"
Foreground="Maroon"
FontWeight="Bold"
Margin="5 2 0 0"
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="2" Margin="10 5">
<Label Content="Switch" />
<ComboBox Style="{StaticResource ErrorComboBox}" ItemsSource="{Binding Switches}" SelectedItem="{Binding SelectedSwitch}"
DisplayMemberPath="Name" HorizontalAlignment="Left">
</ComboBox>
</StackPanel>
<StackPanel Grid.Row="3" Margin="10 10" Style="{StaticResource ErrorStackPanel}">
<RadioButton GroupName="pres"
IsChecked="{Binding TriggerOnPress}"
Content="On" Margin="0 5" />
<RadioButton GroupName="pres"
IsChecked="{Binding TriggerOnPress, Converter={valueconverters:BoolInverterConverter}}"
Content="Off" Margin="0 5"/>
</StackPanel>

StackPanel doesn't have error state. Apply trigger to ComboBox and change bottom margin:
<Style x:Key="ErrorComboBox" TargetType="{x:Type ComboBox}">
<Setter Property="MinWidth" Value="180" />
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
...
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Margin" Value="0 0 0 20"/>
</Trigger>
</Style.Triggers>
</Style>

Related

Trigger command when ListBox selected item changes

I am trying to set up a sort of menu using ListBox and buttons as ListBoxItems to trigger a command when selection changes, but the result is that some times the selected ListBoxItem is changed but the command is not triggered, other times the opposite. The XAML is the following:
<Window.Resources>
<DataTemplate DataType="{x:Type viewModels:TripViewModel}">
<views:TripView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:AddTripViewModel}">
<views:AddTripView />
</DataTemplate>
<Style TargetType="{x:Type Button}">
<Setter Property="Height"
Value="50" />
<Setter Property="Background"
Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border>
<Grid Background="Transparent">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Padding"
Value="3" />
<Setter Property="Background"
Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border BorderBrush="Transparent"
BorderThickness="0"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Background"
Value="DarkCyan" />
</Trigger>
<Trigger Property="IsSelected"
Value="True">
<Setter Property="Background"
Value="DarkCyan" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Window.Content>
<DockPanel Margin="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="Auto"
Width="Auto"
LastChildFill="True">
<!-- Left Panel -->
<Border BorderBrush="Black"
BorderThickness="0,0,1,0">
<StackPanel DockPanel.Dock="Left"
Margin="0"
Background="#555D6F">
<!-- First Row: Stacco Image -->
<Image Height="183"
Width="275"
Margin="3"
Source="/Media/stacco.png" />
<!-- Second Row: Buttons -->
<ScrollViewer CanContentScroll="True"
VerticalAlignment="Stretch"
VerticalScrollBarVisibility="Auto"
Margin="0,10,0,0">
<ListBox Name="MenuButtons"
ItemsSource="{Binding PageViewModels}"
Background="#555D6F"
IsSynchronizedWithCurrentItem="True">
<ListBox.ItemTemplate>
<ItemContainerTemplate>
<Button Content="{Binding Name}"
Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
Margin="0" />
</ItemContainerTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
</StackPanel>
</Border>
<!-- Control Area: Different View made by controls -->
<ContentControl DockPanel.Dock="Right"
Content="{Binding CurrentPageViewModel}" />
</DockPanel>
</Window.Content>
Am I doing right trying to insert a button in the ItemContainerTemplate? Would it be better to use the code behind to trigger the selection changed?

How to display multiple images as thumbnails in xaml

I am trying to create xaml page in silver light application. How to create a page like this, I have created a xaml page, but I can't create like this, my code is...
<UserControl x:Class="XXX.Views.Attachment.AttachmentViewer"
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:xxx.Controls"
xmlns:local2="clr-namespace:xxx.Controls"
xmlns:XXX="clr-namespace:xxx.Controls;assembly=XXX.SL"
xmlns:baseconverters="clr-namespace:System.Windows.Converters;assembly=XXX.SL"
mc:Ignorable="d"
d:DesignHeight="800" FontFamily="{StaticResource MainFont}" d:DesignWidth="350">
<Grid x:Name="LayoutRoot" >
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.Resources>
<Style x:Key="HeaderStyle" TargetType="TextBlock" >
<Setter Property="Margin" Value="5"/>
<Setter Property="TextAlignment" Value="Center"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="20"/>
</Style>
</Grid.Resources>
<TextBlock Text="attachments" Style="{StaticResource HeaderStyle}"/>
<Rectangle Height="2" VerticalAlignment="Bottom" Fill="{StaticResource ColorDefaultGray}" Margin="0,40,0,5"/>
<ListView Grid.Row="1" x:Name="FileListItemsControl" VerticalAlignment="Top" Height="200" Margin="20" >
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding Thumbnail, Converter={StaticResource ThumbnailToImageConverter}}" Height="150" Width="300" />
<TextBlock Text="{Binding FileName}" Style="{StaticResource BodyTextBlockStyle}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</UserControl>
it shows the name ListView does not exist, please find the attached image.
ListView is not found because it is not part of the version of Silverlight you are using.
You can apply a style to a ListBox control and replacing the item panel template with a WrapPanel from silverlight Toolkit.
Here is a Resource Dictionary with some styles that can be applied to ListBox controls to get he result you displayed in your attached image.
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
xmlns:System="clr-namespace:System;assembly=mscorlib">
<!--Wrapping ListBox Styles-->
<Style x:Key="StretchedItemContainerStyle" TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
<Style x:Key="ListBox_StretchedItemStyle" TargetType="ListBox">
<Setter Property="ItemContainerStyle" Value="{StaticResource StretchedItemContainerStyle}"/>
</Style>
<Style x:Key="ListBox_HorizontalWrapStyle" TargetType="ListBox">
<Setter Property="ItemContainerStyle" Value="{StaticResource StretchedItemContainerStyle}"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<toolkit:WrapPanel Orientation="Horizontal" Margin="0"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<ScrollViewer VerticalScrollBarVisibility="Auto" BorderBrush="{x:Null}" >
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ListBox_VerticalWrapStyle" TargetType="ListBox">
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled" />
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ListBoxItem">
<Setter Property="Margin" Value="0" />
<Setter Property="Padding" Value="0" />
</Style>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate >
<toolkit:WrapPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
<!--End Wrapping ListBox Styles-->
</ResourceDictionary>
With the ListBox_HorizontalWrapStyle you just need to apply it to your target ListBox control
<ListBox Grid.Row="1" x:Name="FileListItemsControl" VerticalAlignment="Top" Height="200" Margin="20" Style={StaticResource ListBox_HorizontalWrapStyle} >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding Thumbnail, Converter={StaticResource ThumbnailToImageConverter}}" Height="150" Width="300" />
<TextBlock Text="{Binding FileName}" Style="{StaticResource BodyTextBlockStyle}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

WPF ListView Highlight Color don't change

I have a ListView with three TextBlock for each Item.
The first one has the default color (black) and the others has the property Foreground set to gray.
When I select an item the color of the first TextBlock becomes blue but the others stay gray and are hard to read.
I want that all the text become white color when the item is selected.
How I do that ?
Edit :
My style :
<UserControl.Resources>
<Style TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
My ListView
<ListView x:Name="lvResultat" Grid.Row="0" Grid.Column="1" Background="{x:Null}"
Margin="4"
HorizontalContentAlignment="Stretch"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding ResultatsRecherche}" SelectedItem="{Binding ResultatSelectione, Mode=TwoWay}" BorderBrush="{x:Null}" MouseDoubleClick="lvResultat_MouseLeftDoubleClick" >
<ListView.ItemTemplate>
<DataTemplate DataType="viewModel:ResultatRechercheViewModel">
<Grid Height="86" Margin="2" >
<Grid.RowDefinitions>
<RowDefinition Height="1.5*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="0.5*"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding Titre}"
FontSize="20" FontWeight="Bold" />
<TextBlock Text="{Binding SousTitre}" Grid.Row="1"
FontStyle="Italic" Foreground="Gray"/>
<TextBlock Text="{Binding Resume}" Grid.Row="2" TextTrimming="WordEllipsis"
Foreground="Gray"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I also tried things like
<Style TargetType="ListViewItem">
<Style.Resources>
<!--<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="White" />-->
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="White" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="White" />
</Style.Resources>
</Style>
EDIT 2 :
I have discovered that the custom style changes the color of Textblock which have the default property as Foreground (black).
If I specife Black for the color of the text of the first textblock, the text doesn't change anymore of color when the item is selected.
Picture :
You could achieve what you are trying to do by converting your code from having DataTemplate for a ListViewItem to having a ControlTemplate
This is what I tried:
ListViewItem Style:
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border x:Name="ContentBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Margin="4">
<Grid Height="86" Margin="2" >
<Grid.RowDefinitions>
<RowDefinition Height="1.5*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="0.5*"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding Titre}"
FontSize="20" FontWeight="Bold" />
<TextBlock Text="{Binding SousTitre}" Grid.Row="1" Name="st"
FontStyle="Italic" Foreground="Gray"/>
<TextBlock Text="{Binding Resume}" Grid.Row="2" TextTrimming="WordEllipsis" Name="r"
Foreground="Gray"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" TargetName="st" Value="White" />
<Setter Property="Foreground" TargetName="r" Value="White" />
<Setter Property="Background" TargetName="ContentBorder" Value="DeepSkyBlue" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and then I removed DataTemplate from the ListView XAML:
<ListView x:Name="lvResultat" Grid.Row="0" Grid.Column="1" Background="{x:Null}"
Margin="4"
HorizontalContentAlignment="Stretch"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding ResultatsRecherche}" SelectedItem="{Binding ResultatSelectione, Mode=TwoWay}" BorderBrush="{x:Null}" >
</ListView>
However, if you must use DateTemplate, then what you could do is have a property called IsSelected on your ViewModel, ResultatRechercheViewModel and then have DataTriggers on that property in your DataTemplate.
Updated DataTemplate:
<ListView.ItemTemplate>
<DataTemplate DataType="viewModel:ResultatRechercheViewModel">
<Grid Height="86" Margin="2" >
<Grid.RowDefinitions>
<RowDefinition Height="1.5*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="0.5*"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding Titre}"
FontSize="20" FontWeight="Bold" />
<TextBlock Text="{Binding SousTitre}" Grid.Row="1" Name="st"
FontStyle="Italic" Foreground="Gray"/>
<TextBlock Text="{Binding Resume}" Grid.Row="2" TextTrimming="WordEllipsis" Name="r"
Foreground="Gray"/>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter Property="Foreground" TargetName="st" Value="White" />
<Setter Property="Foreground" TargetName="r" Value="White" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListView.ItemTemplate>
And, you need to update your ViewModel code to set IsSelected property, Below is code from my MainViewModel:
public ResultatRechercheViewModel ResultatSelectione
{
get { return _resultatSelectione; }
set
{
if (_resultatSelectione != null)
{
_resultatSelectione.IsSelected = false;
}
_resultatSelectione = value;
_resultatSelectione.IsSelected = true;
}
}
Hope this resolves your problem or gives you some ideas to resolve your problem.
Try this syntax
<ListView>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
...
</ListView>
Foreground Try use style for listView items:
<Style TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>

WPF: How to show column value for a Chart.ColumnSeries?

I'm using the WPF Toolkit for a .Net 4.0 application written in C#. I have a Chart containing a Column Series bound to a dictionary. The chart works fine but I'd like to show the actual value of each column, either in a textbox below each column, in the middle of each column, or on top of each column. I've been searching for a while and haven't been able to find any information on this. I set up a style for the chart as well as the ColumnSeries, but have not made any progress yet. Any suggestions?
My Chart xaml is:
xmlns:DV="clr-namespace:System.Windows.Controls.DataVisualization;assembly=System.Windows.Controls.DataVisualization.Toolkit"
xmlns:DVC="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"
...
<Page.Resources>
<Style x:Key="MyChart" TargetType="DVC:Chart">
<Setter Property="PlotAreaStyle">
<Setter.Value>
<Style TargetType="Grid">
<Setter Property="Background" Value="#FF2D2D30" />
</Style>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="NoLegend" TargetType="DV:Legend">
<Setter Property="Visibility" Value="Hidden" />
<Setter Property="Width" Value="0" />
</Style>
<Style x:Key="ColumnSeriesStyle" TargetType="{x:Type DVC:ColumnSeries}">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DVC:ColumnSeries}">
<Canvas x:Name="PlotArea" Visibility="Visible">
<TextBox Text="{Binding Path=Value.Value}" IsReadOnly="True"/>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
...
<DVC:Chart Name="TempChart" Style="{StaticResource MyChart}" LegendStyle="{StaticResource NoLegend}">
<DVC:Chart.Series>
<DVC:ColumnSeries IndependentValueBinding="{Binding Path=Value.Value}"
DepdendentValueBinding="{Binding Path=Value.Value}"
ToolTip="{Binding Path=Value.Value}"
Style="{StaticResource ColumnSeriesStyle}">
<DVC:ColumnSeries.DependentRangeAxis>
<DVC:LinearAxis x:Name="TempYAxis"
</DVC:ColumnSeries.DependentRangeAxis>
</DVC:Chart.Series>
</DVC:Chart>
I managed to style my ColumnSeries with this:
<Style x:Key="ColumnSeriesStyle" TargetType="{x:Type DVC:ColumnSeries}">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DVC:ColumnSeries}">
<Canvas x:Name="PlotArea" Visibility="Visible">
<!-- Actual Values -->
<ListBox x:Name="ActualValueListBox" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"
Background="{StaticResource WindowBackground}" Foreground="#FFBB702F" BorderBrush="#FF2D2D30" ItemsSource="{Binding}" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox HorizontalAlignment="Center" VerticalAlignment="Center" TextAlignment="Center" FontSize="12"
Foreground="{StaticResource ValueForeground}" Background="{StaticResource ValueBackground}" Width="40"
Text="{Binding Path=Value.Value}" />
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" Height="20"
Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DVC:ColumnSeries}}, Path=ActualWidth}"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Change TabItem.Header, when selected, from image to text

I have bumped into a problem to which I am seeking the solution.
I have a tabControl with styles added to it.
I want to display only images on each TabItem.Header and when that tab is selected then hide the image from header and display text (the other, inactive headers will be showing images).
Can anybody provide any help?
<Window.Resources>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid Name="Borderer" Background="#FF777777" Height="70" Width="90">
<ContentPresenter x:Name="ContentTabItem" ContentSource="Header" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="#FF000000" />
<Setter TargetName="Borderer" Property="Background" Value="WhiteSmoke" />
<Setter Property="Header" >
<Setter.Value>
<Grid>
<ContentPresenter ContentSource="Tag" />
</Grid>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<TabControl Height="189" HorizontalAlignment="Left" Margin="94,123,0,0" Name="tabControl1" VerticalAlignment="Top" Width="500">
<TabItem Name="tabItem1" IsSelected="True" >
<TabItem.Tag>
<TextBlock Text="blab lab la" />
</TabItem.Tag>
<TabItem.Header>
<Image Source="images/img1.png" Width="35" Height="35" />
</TabItem.Header>
<TabItem.Content>
<Grid>
<TextBlock Name="aaa" />
</Grid>
</TabItem.Content>
</TabItem>
<TabItem >
<TabItem.Tag>
<TextBlock Text="la lab blab" />
</TabItem.Tag>
<TabItem.Header>
<Image Source="images/img2.png" Width="35" Height="35" />
</TabItem.Header>
<TabItem.Content>
<Grid>
<TextBlock Name="bbb" />
</Grid>
</TabItem.Content>
</TabItem>
</TabControl>
</Grid>
You can actually do this without replacing the whole ControlTemplate on the TabItem. You can just alter the TabItem's HeaderTemplate when the TabItem is selected, making your Style a lot shorter:
<DataTemplate x:Key="SelectedHeaderTemplate" >
<ContentControl Content="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=TabItem},
Path=Tag}" />
</DataTemplate>
<Style TargetType="{x:Type TabItem}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="HeaderTemplate" Value="{StaticResource SelectedHeaderTemplate}" />
</Trigger>
</Style.Triggers>
</Style>

Resources