I have this style:
<Style x:Key="ButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<StackPanel>
<Image Source="{Binding Path=local:AttachedProperties.Image}" Stretch="None" HorizontalAlignment="Center" Margin="0" VerticalAlignment="Top"/>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The problem is that the binding does not work for a button:
<Button HorizontalAlignment="Center" Style="{StaticResource ButtonStyle}" VerticalAlignment="Center" Content="Button" local:AttachedProperties.Image="../Images/UserChart.png" Grid.RowSpan="2"/>
What I'm doing wrong?
By the sounds of it, this is a Silverlight issue. More information at this post:
http://forums.silverlight.net/forums/p/102737/299184.aspx
Related
so I got an TextBox and i made the Style in my Ressource Dictionary like that:
<Style x:Key="TextBoxTemplateBrowser" TargetType="{x:Type TextBox}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border Background="White" CornerRadius="0 0 5 5" BorderBrush="Black" BorderThickness="1">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And my TextBox himself like that:
<TextBox TextWrapping="Wrap" x:Name="tb" Style="{DynamicResource TextBoxTemplateBrowser}"
Text="{Binding Inhalt, RelativeSource={RelativeSource AncestorType=local:ArtikelBezPanel}, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
TextChanged="TextBox_TextChanged"
Height="{Binding Height, RelativeSource={RelativeSource AncestorType=local:ArtikelBezPanel}, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" AcceptsReturn="True" BorderBrush="Black" AcceptsTab="True" VerticalAlignment="Top" BorderThickness="1">
</TextBox>
The Problem what I got now is that, when i try to write in that TextBox I can write anything and there cant be Text displayed what I declare before.
When templating TextBox you need the PART_ContentHost:
eg:
<ScrollViewer Margin="0" x:Name="PART_ContentHost" />
See DOCS for more info!
Replace
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
with
<ScrollViewer Margin="0" x:Name="PART_ContentHost" HorizontalAlignment="Center" VerticalAlignment="Center"/>
and it should work!
I'm having really trouble understanding templates and how to use them and re-use them across my App. I have defined two style templates in a resource dictionary, then in my page load them in the correct control and set the style to the resource in dictionary, but nothing showing in screen, nothing at all. I have the control working in another page but I am trying to make it re-usable, code:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="CustomListBox" TargetType="ListBox">
<Style.Resources>
<Style TargetType="{x:Type Expander}">
<Setter Property="IsExpanded"
Value="{Binding Path=IsSelected,
RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" />
</Style>
<ScrollViewer x:Key="Scroller">
<ScrollViewer.VerticalScrollBarVisibility>
Auto
</ScrollViewer.VerticalScrollBarVisibility>
</ScrollViewer>
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<ItemsPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CustomExpander" TargetType="{x:Type Expander}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<DockPanel>
<ToggleButton
DockPanel.Dock="Top"
Background="Teal"
HorizontalAlignment="Left"
Content="{TemplateBinding Content}"
Foreground="WhiteSmoke"
FontSize="12"
Name="Header"
Padding="1"
>
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<TextBlock Text="{TemplateBinding Content}"/>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<ContentPresenter
Content="{TemplateBinding Content}"
Name="ExpandSite"
Visibility="Collapsed"
DockPanel.Dock="Bottom"
HorizontalAlignment="Center"
VerticalAlignment="Center">
</ContentPresenter>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Implementation:
<UserControl x:Class="Neotek.Contabilidad.UI.Views.AdminView"
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:views="clr-namespace:Neotek.Contabilidad.UI.Views"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="600">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Visual Resources/MenuDesplegableRD.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListBox Grid.Column="0" Style="{StaticResource CustomListBox}" Background="Yellow" Width="200" Height="200">
<Expander Width="200" Height="200" Background="Violet"
Style="{StaticResource CustomExpander}">
<Expander.Header>
<TextBlock Text="Administrar Cuentas"
Foreground="White" />
</Expander.Header>
<WrapPanel>
<Label Margin="20,5,5,5" Foreground="white" Content="Nueva Cuenta"/>
<Label Margin="20,5,5,5" Foreground="white" Content="--------------"/>
<Label Margin="20,5,5,5" Foreground="white" Content="---------------"/>
</WrapPanel>
</Expander>
<Expander Style="{StaticResource CustomExpander}">
<Expander.Header>
<TextBlock Text="Administrar Cuentas"
Foreground="White" />
</Expander.Header>
<WrapPanel>
<Label Margin="20,5,5,5" Foreground="white" Content="Nueva Cuenta"/>
<Label Margin="20,5,5,5" Foreground="white" Content="--------------"/>
<Label Margin="20,5,5,5" Foreground="white" Content="---------------"/>
</WrapPanel>
</Expander>
</ListBox>
</Grid>
</UserControl>
I have this working:
<ListBox ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListBox.Resources>
<Style TargetType="{x:Type Expander}">
<Setter Property="IsExpanded"
Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
</Style>
</ListBox.Resources>
<ListBox.Template>
<ControlTemplate TargetType="{x:Type ListBox}">
<ItemsPresenter/>
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<Expander Background="OliveDrab">
<Expander.Header>
<BulletDecorator>
<BulletDecorator.Bullet>
<Image Width="60" Height="64" HorizontalAlignment="Left" VerticalAlignment="Top" />
</BulletDecorator.Bullet>
<TextBlock Margin="10,0,0,0" Text="Administrar Cuentas" VerticalAlignment="Center" HorizontalAlignment="Stretch" Foreground="White" />
</BulletDecorator>
</Expander.Header>
<WrapPanel>
<Label Margin="20,5,5,5" Foreground="white" Content="Nueva Cuenta"/>
<Label Margin="20,5,5,5" Foreground="white" Content="--------------"/>
<Label Margin="20,5,5,5" Foreground="white" Content="---------------"/>
</WrapPanel>
</Expander>
<Expander Background="OrangeRed">
<Expander.Header>
<BulletDecorator>
<BulletDecorator.Bullet>
<Image Width="64" Height="64" HorizontalAlignment="Left" VerticalAlignment="Top" />
</BulletDecorator.Bullet>
<TextBlock Margin="10,0,0,0" Text="Rubros" VerticalAlignment="Center" HorizontalAlignment="Stretch" Foreground="White" />
</BulletDecorator>
</Expander.Header>
<WrapPanel Orientation="Vertical" >
<Label Margin="20,5,5,5" Foreground="white" Content="----------"/>
<Label Margin="20,5,5,5" Foreground="white" Content="----------------"/>
<Label Margin="20,5,5,5" Foreground="white" Content="----------------"/>
</WrapPanel>
</Expander>
<Expander Background="Teal">
<Expander.Header>
<BulletDecorator>
<BulletDecorator.Bullet>
<Image Width="64" Height="64" HorizontalAlignment="Left" VerticalAlignment="Top" />
</BulletDecorator.Bullet>
<TextBlock Margin="10,0,0,0" Text="Subrubros" VerticalAlignment="Center" HorizontalAlignment="Stretch" Foreground="White" />
</BulletDecorator>
</Expander.Header>
<WrapPanel>
<Label Margin="20,5,5,5" Foreground="white" Content="----------"/>
<Label Margin="20,5,5,5" Foreground="white" Content="-------------------"/>
</WrapPanel>
</Expander>
</ListBox>
Any clues what's happening or what I am getting wrong with templates??
Change background of DockPanel, this will use Background property set in Expander in DockPanel. You have set it to Violet.
<DockPanel Background="{TemplateBinding Background}">
Change ToggleButton Content property to <ToggleButton Content="{TemplateBinding Header}".
This will show your Header content of Expander in ToggleButton. You have set it to 'Administrar Cuentas'.
Change control template of your Expander from
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<TextBlock Text="{TemplateBinding Content}"/>
</ControlTemplate>
to
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<Border BorderBrush="Yellow" BorderThickness="3" CornerRadius="5" Background="{TemplateBinding Background}" Height="24">
<ContentPresenter/>
</Border>
</ControlTemplate>
</ToggleButton.Template>
You are trying to put TextBlock of your Header content(set in XAML) inside TextBlock(template). Now, after change TextBlock of Header content will appear within border. Note here <ContentPresenter/> is pointing to
Header.
These changes are enough. I have also changed Horizontal properties of Expander like :
HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"
/////////// Changed ResourceDictionary //////////
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="CustomListBox" TargetType="ListBox">
<Style.Resources>
<Style TargetType="{x:Type Expander}">
<Setter Property="IsExpanded"
Value="{Binding Path=IsSelected,
RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" />
</Style>
<ScrollViewer x:Key="Scroller">
<ScrollViewer.VerticalScrollBarVisibility>
Auto
</ScrollViewer.VerticalScrollBarVisibility>
</ScrollViewer>
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<ItemsPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CustomExpander" TargetType="{x:Type Expander}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<DockPanel Background="{TemplateBinding Background}">
<ToggleButton
Content="{TemplateBinding Header}"
DockPanel.Dock="Top"
Background="Teal"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Foreground="WhiteSmoke"
FontSize="12"
Name="Header"
Padding="1"
>
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<Border BorderBrush="Yellow" BorderThickness="3" CornerRadius="5" Background="{TemplateBinding Background}" Height="24">
<ContentPresenter/>
</Border>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<ContentPresenter
Content="{TemplateBinding Content}"
Name="ExpandSite"
Visibility="Visible"
DockPanel.Dock="Bottom"
HorizontalAlignment="Center"
VerticalAlignment="Center">
</ContentPresenter>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have touched only your ResourceDictionary, and added background to your second expander.
Output after modifying your styles only.
The following ToggleButton works as expected:
<ToggleButton Command="{Binding ToggleCommand}"
RenderOptions.BitmapScalingMode="HighQuality"
ToolTip=".."
VerticalAlignment="Stretch"
Focusable="False" IsChecked="False" Margin="2" Padding="0"
Style="{StaticResource {x:Static ToolBar.ToggleButtonStyleKey}}">
<Image Source="/..;component/Resources/...png" Height="26"/>
</ToggleButton>
When clicked the implementation of ToggleCommand is executed.
Then I decided to use a style like this:
<Style x:Key="ButtonToggle" TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ToggleButton RenderOptions.BitmapScalingMode="HighQuality"
VerticalAlignment="Stretch"
Focusable="False" IsChecked="False" Margin="2" Padding="0"
Style="{StaticResource {x:Static ToolBar.ToggleButtonStyleKey}}">
<Image Source="/..;component/Resources/...png" Height="26"/>
</ToggleButton>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Together with:
<ToggleButton DockPanel.Dock="Right" Command="{Binding ToggleCommand}" ToolTip=".."
Style="{StaticResource ButtonToggle}" />
The display is ok.
The binding with ToggleCommand is ok.
Just when I click the button the implementation of ToggleCommand is not executed.
Can anybody explain why that is?
you need to bind the command of the control in the controlTemplate
add Command="{TemplateBinding Command}" in the togglebutton within the style as:
<Style x:Key="ButtonToggle" TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ToggleButton RenderOptions.BitmapScalingMode="HighQuality"
Command="{TemplateBinding Command}"
VerticalAlignment="Stretch"
Focusable="False" IsChecked="False" Margin="2" Padding="0"
Style="{StaticResource {x:Static ToolBar.ToggleButtonStyleKey}}">
<Image Source="/..;component/Resources/...png" Height="26"/>
</ToggleButton>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
We want to style a wpf button so that the content set in the button is displayed twice. The reason for this is that we want to achieve a drop shadow effect of the button's content. Out thought was to have two ContentControls in the Button style like below:
<ContentControl x:Name="ContentControl" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
<ContentControl Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Foreground="White" Margin="0,1,0,0" />
So, one ContentControl is for displaying the real content and one ContentControl is for displaying the same content with a little margin so that it gives the effect of being the drop shadow. The problem is that it doesn't show content in both content controls. Only one of them shows content. How can I successfully show content in both content controls?
Also, the dropshadow effect is not an option since the button's content becomes blurry.
Thanks for help!
Buttons with Nested Content:
<Style x:Key="ShadowButton"
TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Rectangle Width="{Binding ActualWidth,
ElementName=presenter}"
Height="{Binding ActualHeight,
ElementName=presenter}">
<Rectangle.Fill>
<VisualBrush AlignmentX="Left"
Stretch="None"
Visual="{Binding ElementName=presenter}" />
</Rectangle.Fill>
<Rectangle.RenderTransform>
<TranslateTransform X="3"
Y="3" />
</Rectangle.RenderTransform>
</Rectangle>
<!-- You can replace the following line to a ContentControl if you absolutely have to -->
<ContentPresenter x:Name="presenter"
ContentSource="Content" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Usage can then be dynamic like:
<Button HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="36"
Style="{StaticResource ShadowButton}">
<StackPanel>
<Button Margin="2"
Content="A" />
<Button Margin="2"
Content="B" />
<TextBox Margin="2"
Text="Blah" />
</StackPanel>
</Button>
By using a VisualBrush your not having 2 ContentControl / ContentPresenter in your Style and are just rendering one into a Brush to fill a rectangle and get your effect.
Duplicating Visual Tree with a Template
Try to have a UserControl do this than a Button in the first place. You need to use a Template if you want to duplicate the Visual Tree in your style.
<Style x:Key="ShadowButton"
TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<ContentControl x:Name="shadow"
ContentTemplate="{TemplateBinding ContentTemplate}"
Foreground="SpringGreen">
<ContentControl.RenderTransform>
<TranslateTransform X="50"
Y="50" />
</ContentControl.RenderTransform>
</ContentControl>
<ContentControl x:Name="presenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
Foreground="SlateBlue" />
</Grid>
<ControlTemplate.Triggers>
<Trigger SourceName="presenter"
Property="IsMouseOver"
Value="True">
<Setter TargetName="shadow"
Property="Foreground"
Value="Teal" />
<Setter TargetName="presenter"
Property="Foreground"
Value="Red" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and usage:
<Button HorizontalAlignment="Center"
VerticalAlignment="Center"
Style="{StaticResource ShadowButton}">
<Button.ContentTemplate>
<DataTemplate>
<StackPanel>
<Button Margin="2"
Content="A"
Foreground="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ContentControl}},
Path=Foreground}" />
<TextBox Margin="2"
Foreground="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ContentControl}},
Path=Foreground}"
Text="Blah" />
</StackPanel>
</DataTemplate>
</Button.ContentTemplate>
</Button>
I tried this in a small dummy application and it works just fine. See if this is what you want.
<Window.Resources>
<Style x:Key="test" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<ContentControl Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"/>
<ContentControl Foreground="DarkGray"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}">
<ContentControl.RenderTransform>
<TranslateTransform Y="2" X="2"/>
</ContentControl.RenderTransform>
</ContentControl>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Button Style="{StaticResource test}">
Test
</Button>
</Grid>
I have created a TabControl in a WPF application I'm writing. I re-templated TabItem so that I could have a button on each tab header to close it. So far, all is well and good.
I decided that I now wanted shiny round buttons instead of the default square ugly things. Also, I wanted to use an image as my buttons content instead of simply setting the content to "X".
My XAML styles/templates:
<Style TargetType="{x:Type Button}" x:Key="EllipseButtonStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Ellipse Fill="{TemplateBinding Background}"
Stroke="{TemplateBinding BorderBrush}"
StrokeThickness="{TemplateBinding BorderThickness}"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"/>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{TemplateBinding Button.Content}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="ClosableTabItemTemplate">
<DockPanel MinWidth="120" Margin="0,0,0,0">
<ContentPresenter
Content="{Binding Path=DisplayName}"
VerticalAlignment="Center"
HorizontalAlignment="Left"/>
<Button
Command="{Binding Path=UnSubscribeApplicationCommand}"
CommandParameter="{Binding Path=DisplayName}"
BorderBrush="Black"
BorderThickness="2"
VerticalContentAlignment="Center"
VerticalAlignment="Center"
HorizontalAlignment="Right"
DockPanel.Dock="Right"
Width="16" Height="16">
<Image Source="closeicon.bmp" Height="8" Width="8"
VerticalAlignment="Center" HorizontalAlignment="Center"/>
<Button.Style>
<Style TargetType="{x:Type Button}"
BasedOn="{StaticResource EllipseButtonStyle}">
<Setter Property="Background"
Value="{StaticResource CloseOffButtonBrush}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource CloseOnButtonBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</DockPanel>
</DataTemplate>
With the above code in place, however, a selected tabs content (and the background as well) seems to shift upwards because of what I assume is the TabItems content moving upwards due to it being selected. Why, then, is the ellipse not shifting with the other content? Anyone have any idea what is going on here?
Sorry for the delayed response - I ended up solving the issue by modeling my TabItem template after the one posted in this blogpost. I believe the issue surfaced due to the fact that my TabItem template was being defined as a DataTemplate, not as a ControlTemplate as it should have been. Here is the new template:
<ControlTemplate x:Key="ClosableTabItemTemplate" TargetType="TabItem">
<Grid SnapsToDevicePixels="true">
<Border x:Name="Bd" Background="{StaticResource TabItemUnselectedBrush}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,0" >
<DockPanel x:Name="ContentPanel">
<Button Command="{Binding Path=UnSubscribeApplicationCommand}" BorderBrush="Black" HorizontalAlignment="Center" Margin="3,0,3,0" VerticalAlignment="Center" Width="16" Height="16" DockPanel.Dock="Right" ToolTip="Close Tab">
<Button.Content>
<Image Source="pack://application:,,,/Resources/Close.png" Height="8" Width="8" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Button.Content>
<Button.Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource EllipseButtonStyle}">
<Setter Property="Background" Value="{StaticResource CloseOffButtonBrush}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource CloseOnButtonBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<ContentPresenter x:Name="Content" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Content="{Binding Path=DisplayName}" RecognizesAccessKey="True" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="{TemplateBinding Padding}"/>
</DockPanel>
</Border>
</Grid>
<!-- bunch of ControlTemplate triggers to style the TabItem background color/position -->
</ControlTemplate>
Whenever I have controls inside a DockPanel, it always seems to play up if one of the controls I've explicitly attached DockPanel.Dock to comes AFTER the element I want to take up the fill portion. While I don't know if this will answer your question, try this instead in your ClosableTabItemTemplate DataTemplate:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter Grid.Column="0"/>
<Button Grid.Column="1"/>
</Grid>