I programmatically add tabitems to a tabcontrol. I have a custom tabItem with two buttons in the header, one to close the tab, the other to do some other functionality (it triggers an ascending or descending sort). The content of close button is a constant, the content of the other button changes based on a boolean value in the tab's datacontext. Only the buttons in the selected tab show in the tab header.
Initially, both buttons will show on the tab created last. The problem I'm experiencing is that as I select tabs, the content of the close button on the newly selected tab will be visible, as it should be, but the content of the bound button is gone (the button is there).
I should point out the content of the problemmatic button is one of two polygons depending on the value of the binding source.
I should also point out that if i click the empty button the appropriate image appears on the tab header.
Adding more confusion is that the tooltip property attached to the button, behaves correctly - it displays the appropriate tooltip text based on the binding source.
The custom TabItem is mostly created from a ResourceDictionary which I've included.
Please help, I admit my wpf knowledge is limited.
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TreeView.Helpers">
<Style x:Key="TabItemFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle SnapsToDevicePixels="true" Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1" Margin="3,3,3,1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="TabControlNormalBorderBrush" Color="#8C8E94"/>
<LinearGradientBrush x:Key="TabItemHotBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#EAF6FD" Offset="0.15"/>
<GradientStop Color="#D9F0FC" Offset=".5"/>
<GradientStop Color="#BEE6FD" Offset=".5"/>
<GradientStop Color="#A7D9F5" Offset="1"/>
</LinearGradientBrush>
<!--Brushes (for Sort Button -->
<!--Light brush, to highlight.-->
<LinearGradientBrush x:Key="lightBrushBack" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#7EFFFFFF" Offset="0"/>
<GradientStop Color="#03FFFFFF" Offset=".4"/>
<GradientStop Color="#00030000" Offset=".5"/>
<GradientStop Color="#0AFFFFFF" Offset=".55"/>
<GradientStop Color="#7EFFFFFF" Offset="1"/>
</LinearGradientBrush>
<!--Normal brush, little darker than light brush.-->
<LinearGradientBrush x:Key="normalBrushBack" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#7EF0F0F0" Offset="0"/>
<GradientStop Color="#03FFFFFF" Offset=".4"/>
<GradientStop Color="#00030000" Offset=".5"/>
<GradientStop Color="#0AFFFFFF" Offset=".55"/>
<GradientStop Color="#3EFFFFFF" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="TabItemSelectedBackground" Color="#F9F9F9"/>
<SolidColorBrush x:Key="TabItemHotBorderBrush" Color="#3C7FB1"/>
<SolidColorBrush x:Key="TabItemDisabledBackground" Color="#F4F4F4"/>
<SolidColorBrush x:Key="TabItemDisabledBorderBrush" Color="#FFC9C7BA"/>
<Style TargetType="{x:Type local:CloseableTabItem}" >
<Style.Resources>
<LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#F3F3F3" Offset="0"/>
<GradientStop Color="#EBEBEB" Offset="0.5"/>
<GradientStop Color="#DDDDDD" Offset="0.5"/>
<GradientStop Color="#CDCDCD" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ButtonOverBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFFAFAFA" Offset="0"/>
<GradientStop Color="#FFE0E0E3" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ButtonPressedBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFE0E0E2" Offset="0"/>
<GradientStop Color="#FFF8F8F8" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF969696"/>
<local:VisibilityConverter x:Key="converter" />
<Style x:Key="CloseableTabItemButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Visibility" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=TabItem}, Path=IsSelected, Converter={StaticResource converter}}"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="4"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border SnapsToDevicePixels="true" x:Name="Chrome"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="2" Opacity="0" />
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
RecognizesAccessKey="True"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" TargetName="Chrome" Value="1"/>
<Setter Property="Background" TargetName="Chrome" Value="{DynamicResource ButtonOverBackground}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Opacity" TargetName="Chrome" Value="1"/>
<Setter Property="Background" TargetName="Chrome" Value="{DynamicResource ButtonPressedBackground}" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="SortableButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Visibility" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=TabItem}, Path=IsSelected, Converter={StaticResource converter}}"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="4"/>
<Setter Property="Content">
<Setter.Value>
<Polygon Points="1,1 4,7.5 7.5,1" Stroke="Black" Fill="Black" />
</Setter.Value>
</Setter>
<Setter Property="ToolTip" Value="Sort the Tree Descending" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border SnapsToDevicePixels="true" x:Name="Chrome"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="2" Opacity="0" />
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
RecognizesAccessKey="True"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" TargetName="Chrome" Value="1"/>
<Setter Property="Background" TargetName="Chrome" Value="{DynamicResource ButtonOverBackground}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Opacity" TargetName="Chrome" Value="1"/>
<Setter Property="Background" TargetName="Chrome" Value="{DynamicResource ButtonPressedBackground}" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabItem}}, Path=DataContext.SortDirectionIsAscending}" Value="false">
<Setter Property="Content">
<Setter.Value>
<Polygon Points="1,8 4,1.5 7.5,8" Stroke="Black" Fill="Black" />
</Setter.Value>
</Setter>
<Setter Property="ToolTip" Value="Sort the Tree Ascending" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Setter Property="FocusVisualStyle" Value="{StaticResource TabItemFocusVisual}"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Padding" Value="6,1,6,1"/>
<Setter Property="BorderBrush" Value="{StaticResource TabControlNormalBorderBrush}"/>
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CloseableTabItem}">
<Grid SnapsToDevicePixels="true">
<Border x:Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,0" >
<DockPanel x:Name="ContentPanel">
<Grid DockPanel.Dock="Right">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" x:Name="PART_Sort"
HorizontalAlignment="Center"
Margin="3,0,3,0"
VerticalAlignment="Center"
Width="16"
Height="16"
Style="{DynamicResource SortableButtonStyle}"
Command="{Binding SortTabCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabControl}}}">
</Button>
<Button Grid.Column="1" x:Name="PART_Close"
HorizontalAlignment="Center"
Margin="3,0,3,0"
VerticalAlignment="Center"
Width="16"
Height="16"
Style="{DynamicResource CloseableTabItemButtonStyle}"
ToolTip="Close Tab"
Command="{Binding CloseTabCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabControl}}}">
<Path x:Name="Path"
Stretch="Fill"
StrokeThickness="0.5"
Stroke="#FF333333"
Fill="#FF969696"
Data="F1 M 2.28484e-007,1.33331L 1.33333,0L 4.00001,2.66669L 6.66667,6.10352e-005L 8,1.33331L 5.33334,4L 8,6.66669L 6.66667,8L 4,5.33331L 1.33333,8L 1.086e-007,6.66669L 2.66667,4L 2.28484e-007,1.33331 Z "
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
</Button>
</Grid>
<ContentPresenter x:Name="Content" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="Header" RecognizesAccessKey="True" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="{TemplateBinding Padding}"/>
</DockPanel>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" SourceName="PART_Close" Value="True">
<Setter Property="Fill" TargetName="Path" Value="#FFB83C3D"/>
</Trigger>
<Trigger Property="IsPressed" SourceName="PART_Close" Value="True">
<Setter Property="Fill" TargetName="Path" Value="#FF9D0000"/>
</Trigger>
<Trigger Property="IsMouseOver" SourceName="PART_Sort" Value="True">
<Setter Property="Fill" TargetName="Path" Value="#FFB83C3D"/>
</Trigger>
<Trigger Property="IsPressed" SourceName="PART_Sort" Value="True">
<Setter Property="Fill" TargetName="Path" Value="#FF9D0000"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="Bd" Value="{StaticResource TabItemHotBackground}"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Panel.ZIndex" Value="1"/>
<Setter Property="Background" TargetName="Bd" Value="{StaticResource TabItemSelectedBackground}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="false"/>
<Condition Property="IsMouseOver" Value="true"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource TabItemHotBorderBrush}"/>
</MultiTrigger>
<Trigger Property="TabStripPlacement" Value="Bottom">
<Setter Property="BorderThickness" TargetName="Bd" Value="1,0,1,1"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Left">
<Setter Property="BorderThickness" TargetName="Bd" Value="1,1,0,1"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Right">
<Setter Property="BorderThickness" TargetName="Bd" Value="0,1,1,1"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Top"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-2,-2,-2,-1"/>
<Setter Property="Margin" TargetName="ContentPanel" Value="0,0,0,1"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Bottom"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-2,-1,-2,-2"/>
<Setter Property="Margin" TargetName="ContentPanel" Value="0,1,0,0"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Left"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-2,-2,-1,-2"/>
<Setter Property="Margin" TargetName="ContentPanel" Value="0,0,1,0"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Right"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-1,-2,-2,-2"/>
<Setter Property="Margin" TargetName="ContentPanel" Value="1,0,0,0"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="Bd" Value="{StaticResource TabItemDisabledBackground}"/>
<Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource TabItemDisabledBorderBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
I solved my own problem. In my attempt at solving this, I went with a togglebutton and an image instead of a regular button and a polygon. I then realized I was missing the trigger condition for the selected state of the tabitem. The final solution is included here, for anyone interested. By the way, the idea, and the majority of the style, to create a control that inherits from a tabitem came from this site: http://www.c-sharpcorner.com/uploadfile/dpatra/closable-tab-control-in-wpf/.
Lastly, for those presumptuous folks out there, this problem had nothing to do with MVVM.
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TreeView.Helpers">
<ImageSource x:Key="Image_DescendingGreySortButton">../Images/imgSortDescendingButtonGrey.PNG</ImageSource>
<ImageSource x:Key="Image_AscendingGreySortButton">../Images/imgSortAscendingButtonGrey.PNG</ImageSource>
<Style x:Key="TabItemFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle SnapsToDevicePixels="true" Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1" Margin="3,3,3,1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="TabControlNormalBorderBrush" Color="#8C8E94"/>
<LinearGradientBrush x:Key="TabItemHotBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#EAF6FD" Offset="0.15"/>
<GradientStop Color="#D9F0FC" Offset=".5"/>
<GradientStop Color="#BEE6FD" Offset=".5"/>
<GradientStop Color="#A7D9F5" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="TabItemSelectedBackground" Color="#F9F9F9"/>
<SolidColorBrush x:Key="TabItemHotBorderBrush" Color="#3C7FB1"/>
<SolidColorBrush x:Key="TabItemDisabledBackground" Color="#F4F4F4"/>
<SolidColorBrush x:Key="TabItemDisabledBorderBrush" Color="#FFC9C7BA"/>
<Style TargetType="{x:Type local:CloseableTabItem}" >
<Style.Resources>
<LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#F3F3F3" Offset="0"/>
<GradientStop Color="#EBEBEB" Offset="0.5"/>
<GradientStop Color="#DDDDDD" Offset="0.5"/>
<GradientStop Color="#CDCDCD" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ButtonOverBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFFAFAFA" Offset="0"/>
<GradientStop Color="#FFE0E0E3" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ButtonPressedBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFE0E0E2" Offset="0"/>
<GradientStop Color="#FFF8F8F8" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ToggleButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#F3F3F3" Offset="0"/>
<GradientStop Color="#EBEBEB" Offset="0.5"/>
<GradientStop Color="#DDDDDD" Offset="0.5"/>
<GradientStop Color="#CDCDCD" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ToggleButtonOverBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFFAFAFA" Offset="0"/>
<GradientStop Color="#FFE0E0E3" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ToggleButtonPressedBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFE0E0E2" Offset="0"/>
<GradientStop Color="#FFF8F8F8" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF969696"/>
<SolidColorBrush x:Key="ToggleButtonNormalBorder" Color="#FF969696"/>
<local:VisibilityConverter x:Key="converter" />
<Style x:Key="CloseableTabItemButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Visibility" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=TabItem}, Path=IsSelected, Converter={StaticResource converter}}"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="4"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border SnapsToDevicePixels="true" x:Name="Chrome"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="2" Opacity="0" />
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
RecognizesAccessKey="True"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" TargetName="Chrome" Value="1"/>
<Setter Property="Background" TargetName="Chrome" Value="{DynamicResource ButtonOverBackground}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Opacity" TargetName="Chrome" Value="1"/>
<Setter Property="Background" TargetName="Chrome" Value="{DynamicResource ButtonPressedBackground}" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ToggleButton}" x:Key="ToggleButtonStyle">
<Setter Property="Visibility" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=TabItem}, Path=IsSelected, Converter={StaticResource converter}}"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Background" Value="{StaticResource ToggleButtonNormalBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource ToggleButtonNormalBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="ToolTip" Value="Sort the Tree Descending" />
<Setter Property="Content" Value="{DynamicResource Image_DescendingGreySortButton}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid>
<Border SnapsToDevicePixels="true" x:Name="Chrome"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="2" Opacity="0" />
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
RecognizesAccessKey="True"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" TargetName="Chrome" Value="1"/>
<Setter Property="Background" TargetName="Chrome" Value="{DynamicResource ButtonOverBackground}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Opacity" TargetName="Chrome" Value="1"/>
<Setter Property="Background" TargetName="Chrome" Value="{DynamicResource ButtonPressedBackground}" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Setter Property="FocusVisualStyle" Value="{StaticResource TabItemFocusVisual}"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Padding" Value="6,1,6,1"/>
<Setter Property="BorderBrush" Value="{StaticResource TabControlNormalBorderBrush}"/>
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CloseableTabItem}">
<Grid SnapsToDevicePixels="true">
<Border x:Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,0" >
<DockPanel x:Name="ContentPanel">
<Grid DockPanel.Dock="Right">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ToggleButton Grid.Column="0" x:Name="PART_Sort"
HorizontalAlignment="Center"
Margin="3,0,3,0"
VerticalAlignment="Center"
Width="16"
Height="16"
Style="{DynamicResource ToggleButtonStyle}"
IsThreeState="False"
Command="{Binding SortTabCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabControl}}}">
</ToggleButton>
<Button Grid.Column="1" x:Name="PART_Close"
HorizontalAlignment="Center"
Margin="3,0,3,0"
VerticalAlignment="Center"
Width="16"
Height="16"
Style="{DynamicResource CloseableTabItemButtonStyle}"
ToolTip="Close Tab"
Command="{Binding CloseTabCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabControl}}}">
<Path x:Name="Path"
Stretch="Fill"
StrokeThickness="0.5"
Stroke="#FF333333"
Fill="#FF969696"
Data="F1 M 2.28484e-007,1.33331L 1.33333,0L 4.00001,2.66669L 6.66667,6.10352e-005L 8,1.33331L 5.33334,4L 8,6.66669L 6.66667,8L 4,5.33331L 1.33333,8L 1.086e-007,6.66669L 2.66667,4L 2.28484e-007,1.33331 Z "
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
</Button>
</Grid>
<ContentPresenter x:Name="Content" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="Header" RecognizesAccessKey="True" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="{TemplateBinding Padding}"/>
</DockPanel>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" SourceName="PART_Close" Value="True">
<Setter Property="Fill" TargetName="Path" Value="#FFB83C3D"/>
</Trigger>
<Trigger Property="IsPressed" SourceName="PART_Close" Value="True">
<Setter Property="Fill" TargetName="Path" Value="#FF9D0000"/>
</Trigger>
<Trigger Property="IsMouseOver" SourceName="PART_Sort" Value="True">
<Setter Property="Fill" TargetName="Path" Value="#FFB83C3D"/>
</Trigger>
<Trigger Property="IsPressed" SourceName="PART_Sort" Value="True">
<Setter Property="Fill" TargetName="Path" Value="#FF9D0000"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="Bd" Value="{StaticResource TabItemHotBackground}"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Panel.ZIndex" Value="1"/>
<Setter Property="Background" TargetName="Bd" Value="{StaticResource TabItemSelectedBackground}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="false"/>
<Condition Property="IsMouseOver" Value="true"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource TabItemHotBorderBrush}"/>
</MultiTrigger>
<Trigger Property="TabStripPlacement" Value="Bottom">
<Setter Property="BorderThickness" TargetName="Bd" Value="1,0,1,1"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Left">
<Setter Property="BorderThickness" TargetName="Bd" Value="1,1,0,1"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Right">
<Setter Property="BorderThickness" TargetName="Bd" Value="0,1,1,1"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Top"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-2,-2,-2,-1"/>
<Setter Property="Margin" TargetName="ContentPanel" Value="0,0,0,1"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Bottom"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-2,-1,-2,-2"/>
<Setter Property="Margin" TargetName="ContentPanel" Value="0,1,0,0"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Left"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-2,-2,-1,-2"/>
<Setter Property="Margin" TargetName="ContentPanel" Value="0,0,1,0"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Right"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-1,-2,-2,-2"/>
<Setter Property="Margin" TargetName="ContentPanel" Value="1,0,0,0"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="Bd" Value="{StaticResource TabItemDisabledBackground}"/>
<Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource TabItemDisabledBorderBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="True"/>
<Condition Property="IsChecked" SourceName="PART_Sort" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Content" TargetName="PART_Sort">
<Setter.Value>
<Image>
<Image.Style>
<Style TargetType="Image">
<Setter Property="Source" Value="{DynamicResource Image_AscendingGreySortButton}" />
</Style>
</Image.Style>
</Image>
</Setter.Value>
</Setter>
<Setter Property="ToolTip" TargetName="PART_Sort" Value="Sort the Tree Ascending" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="True"/>
<Condition Property="IsChecked" SourceName="PART_Sort" Value="False" />
</MultiTrigger.Conditions>
<Setter Property="Content" TargetName="PART_Sort">
<Setter.Value>
<Image>
<Image.Style>
<Style TargetType="Image">
<Setter Property="Source" Value="{DynamicResource Image_DescendingGreySortButton}" />
</Style>
</Image.Style>
</Image>
</Setter.Value>
</Setter>
<Setter Property="ToolTip" TargetName="PART_Sort" Value="Sort the Tree Descending" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
There are a few solutions here for Closeable tabs but they all depend on the owner of the collection to provide the closing functionality.
I thought perhaps it would be possible by creating a Custom TabControl and TabItem that this could be done in the CodeBehind.
The idea would be to somehow alert the TabControl from the TabItem that the close button has been pressed (perhaps with a bubbling event or something, please suggest) and then remove that particular items wrapped in that TabItem from the ItemsSource.
Problem is I'm not sure how or even if this is possible. Can you somehow remove items from a collection set as ItemsSource in a TabControl? Could we perhaps set a new DP sow we have full control over the Collection and just set that as ItemsSource in Code Behind.
Anyone done this or has any ideas hwo to do this. Is it even possible at all?
Even if that's technically possible, I'd advise sticking to M-V-VM. Let the owner of the collection i.e. the ViewModel control adding/deleting items from the collection.
Let the View be thin and sync with the VM's collection via data-binding. This keeps the Views from getting complex and eliminates the GUI which is a deterrent to testability.
You should find that as the path of least WPF resistance.
This came up in our application, so I figured I would post my solution. ClosableTabControl closes any tab by removing the item from the bound ItemsSource. This is partially scraped from other solutions (Szymon Kobalczyk et al.).
ClosableTabControl.cs:
[StyleTypedProperty(Property = "ItemContainerStyle", StyleTargetType = typeof(ClosableTabItem))]
public class ClosableTabControl : TabControl
{
static ClosableTabControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ClosableTabControl),
new FrameworkPropertyMetadata(typeof(ClosableTabControl)));
CloseTabCommand = new RoutedCommand();
}
public ClosableTabControl()
: base()
{
CommandBindings.Add(new CommandBinding(CloseTabCommand, CloseTabCommand_Execute));
}
public static ICommand CloseTabCommand { get; private set; }
private void CloseTabCommand_Execute(object sender, ExecutedRoutedEventArgs args)
{
if (args.Parameter == null || !(args.Parameter is ClosableTabItem))
throw new ArgumentNullException("parameter must be of type ClosableTabItem");
var item = this.ItemContainerGenerator.ItemFromContainer((ClosableTabItem)args.Parameter);
if (item == null)
throw new InvalidOperationException("Item not in collection");
IEditableCollectionView view = this.Items;
if (!view.CanRemove)
throw new InvalidOperationException("Read-only collection");
view.Remove(item);
}
protected override DependencyObject GetContainerForItemOverride()
{
return new ClosableTabItem();
}
}
ClosableTabItem.cs:
public class ClosableTabItem : TabItem
{
static ClosableTabItem()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ClosableTabItem),
new FrameworkPropertyMetadata(typeof(ClosableTabItem)));
}
}
Themes/Generic.xaml:
<Style TargetType="{x:Type local:ClosableTabControl}" BasedOn="{StaticResource {x:Type TabControl}}" />
<Style x:Key="TabItemFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle SnapsToDevicePixels="true" Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1" Margin="3,3,3,1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="TabControlNormalBorderBrush" Color="#8C8E94"/>
<LinearGradientBrush x:Key="TabItemHotBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#EAF6FD" Offset="0.15"/>
<GradientStop Color="#D9F0FC" Offset=".5"/>
<GradientStop Color="#BEE6FD" Offset=".5"/>
<GradientStop Color="#A7D9F5" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="TabItemSelectedBackground" Color="#F9F9F9"/>
<SolidColorBrush x:Key="TabItemHotBorderBrush" Color="#3C7FB1"/>
<SolidColorBrush x:Key="TabItemDisabledBackground" Color="#F4F4F4"/>
<SolidColorBrush x:Key="TabItemDisabledBorderBrush" Color="#FFC9C7BA"/>
<Style TargetType="{x:Type local:ClosableTabItem}">
<Style.Resources>
<LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#F3F3F3" Offset="0"/>
<GradientStop Color="#EBEBEB" Offset="0.5"/>
<GradientStop Color="#DDDDDD" Offset="0.5"/>
<GradientStop Color="#CDCDCD" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ButtonOverBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFFAFAFA" Offset="0"/>
<GradientStop Color="#FFE0E0E3" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ButtonPressedBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFE0E0E2" Offset="0"/>
<GradientStop Color="#FFF8F8F8" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF969696"/>
<Style x:Key="CloseableTabItemButtonStyle" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="4"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border SnapsToDevicePixels="true" x:Name="Chrome" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2" Opacity="0" />
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" TargetName="Chrome" Value="1"/>
<Setter Property="Background" TargetName="Chrome" Value="{DynamicResource ButtonOverBackground}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Opacity" TargetName="Chrome" Value="1"/>
<Setter Property="Background" TargetName="Chrome" Value="{DynamicResource ButtonPressedBackground}" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Setter Property="FocusVisualStyle" Value="{StaticResource TabItemFocusVisual}"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Padding" Value="6,1,6,1"/>
<Setter Property="BorderBrush" Value="{StaticResource TabControlNormalBorderBrush}"/>
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ClosableTabItem}">
<Grid SnapsToDevicePixels="true">
<Border x:Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,0" >
<DockPanel x:Name="ContentPanel">
<Button x:Name="PART_Close" HorizontalAlignment="Center" Margin="3,0,3,0" VerticalAlignment="Center" Width="16" Height="16" DockPanel.Dock="Right" Style="{DynamicResource CloseableTabItemButtonStyle}" ToolTip="Close" Command="{x:Static local:ClosableTabControl.CloseTabCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:ClosableTabItem}}}">
<Path x:Name="Path" Stretch="Fill" StrokeThickness="0.5" Stroke="#FF333333" Fill="#FF969696" Data="F1 M 2.28484e-007,1.33331L 1.33333,0L 4.00001,2.66669L 6.66667,6.10352e-005L 8,1.33331L 5.33334,4L 8,6.66669L 6.66667,8L 4,5.33331L 1.33333,8L 1.086e-007,6.66669L 2.66667,4L 2.28484e-007,1.33331 Z " HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Button>
<ContentPresenter x:Name="Content" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="Header" RecognizesAccessKey="True" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="{TemplateBinding Padding}"/>
</DockPanel>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" SourceName="PART_Close" Value="True">
<Setter Property="Fill" TargetName="Path" Value="#FFB83C3D"/>
</Trigger>
<Trigger Property="IsPressed" SourceName="PART_Close" Value="True">
<Setter Property="Fill" TargetName="Path" Value="#FF9D3838"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="Bd" Value="{StaticResource TabItemHotBackground}"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Panel.ZIndex" Value="1"/>
<Setter Property="Background" TargetName="Bd" Value="{StaticResource TabItemSelectedBackground}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="false"/>
<Condition Property="IsMouseOver" Value="true"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource TabItemHotBorderBrush}"/>
</MultiTrigger>
<Trigger Property="TabStripPlacement" Value="Bottom">
<Setter Property="BorderThickness" TargetName="Bd" Value="1,0,1,1"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Left">
<Setter Property="BorderThickness" TargetName="Bd" Value="1,1,0,1"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Right">
<Setter Property="BorderThickness" TargetName="Bd" Value="0,1,1,1"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Top"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-2,-2,-2,-1"/>
<Setter Property="Margin" TargetName="ContentPanel" Value="0,0,0,1"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Bottom"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-2,-1,-2,-2"/>
<Setter Property="Margin" TargetName="ContentPanel" Value="0,1,0,0"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Left"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-2,-2,-1,-2"/>
<Setter Property="Margin" TargetName="ContentPanel" Value="0,0,1,0"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Right"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-1,-2,-2,-2"/>
<Setter Property="Margin" TargetName="ContentPanel" Value="1,0,0,0"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="Bd" Value="{StaticResource TabItemDisabledBackground}"/>
<Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource TabItemDisabledBorderBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Having trouble figuring how out to have the text change styles when the text is changed. I have it set up so the styles change when I am typing and the default is set to be grayed out to indicate what needs to go in that field. I want the text to be black and of normal font weight when it is changed from the default text and to remain that way.
Here are my current trigger styles
<Style TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="DimGray" />
<Setter Property="FontSize" Value="15" />
<Setter Property="FontStyle" Value="Italic" />
<Setter Property="Padding" Value="5,4,0,4" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBoxBase}">
<Border
x:Name="Bd"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="7"
>
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="2,1">
<GradientStop Color="{Binding Path=GradientColorStart}" Offset="0"/>
<GradientStop Color="{Binding Path=GradientColorEnd}" Offset="1"/>
<!--
<GradientStop Color="#CCCCCC" Offset="0"/>
<GradientStop Color="#FFFFFF" Offset="1"/>
-->
</LinearGradientBrush>
</Border.Background>
<ScrollViewer x:Name="PART_ContentHost"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter
Property="Background"
TargetName="Bd"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
/>
<Setter Property="Foreground" Value="Green"/>
</Trigger>
<Trigger Property="Width" Value="Auto">
<Setter Property="MinWidth" Value="100"/>
</Trigger>
<Trigger Property="Height" Value="Auto">
<Setter Property="MinHeight" Value="20"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="FontStyle" Value="Normal" />
<Setter Property="Text" Value="" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="#00112d" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="FontStyle" Value="Normal" />
</Trigger>
</Style.Triggers>
</Style>
This is something i would approach with the TargetNullValue of bindings, the string has to be null at first of course, so this might not be an option for you:
<TextBox Text="{Binding TestString, TargetNullValue=Enter Text Here, UpdateSourceTrigger=PropertyChanged}">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding TestString}" Value="{x:Null}">
<Setter Property="Foreground" Value="{StaticResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
I have to create a custom styled button. The problem is that although i change everything when mouseovering it or when it has focus it gets the original colors!
Tried to set FocusVisualStyle="{x:Null}" but it keeps doing it....
<Button Content="Button" Height="143" Margin="85,76,190,0" VerticalAlignment="Top" FocusVisualStyle="{x:Null}" Background="#FFE9D7D7"/>
what can i do?
The visuals you are seeing may be coming from the default control template, which includes window chrome. You may want to try creating a custom template for the button, which will give you full controls of the visual elements.
The default button template is the overriding your style. so you have crete your own control template for the button. Here is one example.
<Style x:Key="InformButton" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Margin" Value="2"/>
<Setter Property="FontFamily" Value="Verdana"/>
<Setter Property="FontSize" Value="11px"/>
<Setter Property="FontWeight" Value="Bold"/>
<!--<Setter Property="FocusVisualStyle" Value="{StaticResource MyFocusVisual}" />-->
<Setter Property="Background" >
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1" >
<GradientStop Color="#FFFFD190" Offset="0.2"/>
<GradientStop Color="Orange" Offset="0.85"/>
<GradientStop Color="#FFFFD190" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border"
BorderThickness="1"
Padding="4,2"
BorderBrush="DarkGray"
CornerRadius="3"
Background="{TemplateBinding Background}">
<Grid >
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center" Name="contentShadow"
>
<ContentPresenter.RenderTransform>
<TranslateTransform X="1.0" Y="1.0" />
</ContentPresenter.RenderTransform>
</ContentPresenter>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center" Name="content"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="#FF4788c8" />
<Setter Property="Foreground" Value="#FF4788c8" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" >
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1" >
<GradientStop Color="#FFFFD190" Offset="0.35"/>
<GradientStop Color="Orange" Offset="0.95"/>
<GradientStop Color="#FFFFD190" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter TargetName="content" Property="RenderTransform" >
<Setter.Value>
<TranslateTransform Y="1.0" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsDefaulted" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="#FF282828" />
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="#FF282828" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="border" Property="Opacity" Value="0.7" />
<Setter Property="Foreground" Value="Gray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Even though you defined a custom style, the button still inherits some properties from the default style if you didn't set them in your custom style. So you have two options:
set OverridesDefaultStyle to true on the button so that it doesn't inherit the default style
set the background/border/foreground brushes explicitly in the custom style
Update: using Expression Blend 3
I'm trying to style the IsPressed & IsEnabled(false) property triggers for a class of buttons in a WPF application.
Here's a UserControl with a Button using the style...
<UserControl
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"
mc:Ignorable="d"
x:Class="Kiosk.ButtonTest"
x:Name="UserControl">
<Grid x:Name="LayoutRoot">
<Button HorizontalAlignment="Left" Style="{DynamicResource BlueButton}" VerticalAlignment="Top" Width="155" Content="Button" Height="52.9"/>
</Grid>
</UserControl>
And here's the style fragment...
<!-- Blue Button -->
<Style x:Key="BlueButton" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource BlueGradient3}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="{DynamicResource DarkGradient1}"/>
<Setter Property="BorderBrush" Value="{DynamicResource BlueGradient3}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{DynamicResource DarkGradient1}"/>
<Setter Property="BorderBrush" Value="{DynamicResource BlueGradient1}"/>
</Trigger>
</Style.Triggers>
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Setter Property="Background" Value="{DynamicResource BlueGradient1}"/>
<Setter Property="BorderBrush" Value="{DynamicResource BlueGradient2}"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="TextBox.TextAlignment" Value="Center"/>
<Setter Property="FontFamily" Value="Trebuchet MS"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="Effect" Value="{DynamicResource KioskStandardDropShadow}" />
</Style>
<LinearGradientBrush x:Key="BlueGradient1" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF3FA2FD" Offset="0"/>
<GradientStop Color="#FF014782" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="BlueGradient2" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF014782" Offset="0"/>
<GradientStop Color="#FF3FA2FD" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="BlueGradient3" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF014782" Offset="1"/>
<GradientStop Color="#FF0B2135" Offset="0"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="DarkGradient1" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF2A2A2A" Offset="0"/>
<GradientStop Color="#FF474747" Offset="0.478"/>
<GradientStop Color="#FF323232" Offset="0.487"/>
<GradientStop Color="Black" Offset="1"/>
<GradientStop Color="#FF282828" Offset="0.681"/>
</LinearGradientBrush>
<!-- Regular Drop Shadow -->
<DropShadowEffect x:Key="KioskStandardDropShadow" Opacity="0.6" BlurRadius="10" ShadowDepth="5" Direction="308"/>
<!-- fragment end -->
The Default and Mouse over changes work fine, but isEnabled false and isPressed true still show the Button default colors.
What am I doing wrong?
I fixed it after studying the code at http://mark-dot-net.blogspot.com/2007/07/creating-custom-wpf-button-template-in.html...
This is what I ended up with, which works great.
<!-- Blue Button -->
<Style x:Key="BlueButton" TargetType="{x:Type Button}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border"
BorderThickness="2"
Padding="4,2"
BorderBrush="{DynamicResource BlueGradient2}"
CornerRadius="5"
Background="{TemplateBinding Background}">
<Grid >
<ContentPresenter
HorizontalAlignment="Center"
VerticalAlignment="Center"
Name="content"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource BlueGradient3}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="{DynamicResource DarkGradient1}"/>
<Setter Property="BorderBrush" Value="{DynamicResource BlueGradient3}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{DynamicResource DarkGradient1}"/>
<Setter Property="BorderBrush" Value="{DynamicResource BlueGradient1}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Setter Property="Background" Value="{DynamicResource BlueGradient1}"/>
<Setter Property="BorderBrush" Value="{DynamicResource BlueGradient2}"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="TextBox.TextAlignment" Value="Center"/>
<Setter Property="FontFamily" Value="Trebuchet MS"/>
<Setter Property="FontSize" Value="15pt"/>
<Setter Property="Effect" Value="{DynamicResource KioskStandardDropShadow}" />
</Style>
You need to replace the ControlTemplate to change the background color of your button.
Here is one I copied from MSDN that works well with your code.
You can merge your specific overrides to this style.
EDIT:
To make the following style work, as is, you need to download the Styling with Control Templates Sample from Microsoft. If you include Button.xaml and Shared.xaml from the sample the following style should work because these two files contain all the StaticResoruces listed the XAML below. I am testing in Visual Studio 2008.
Here is how I chanaged the user conttrol:
<UserControl x:Class="ButtonPressed.Views.KioskButton"
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"
mc:Ignorable="d"
Height="300" Width="300">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="Button.xaml">
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Button HorizontalAlignment="Left" VerticalAlignment="Top" Width="155" Content="Button" Height="52.9"/>
</Grid>
</UserControl>
Here is part of the button style from Button.xaml:
<Style TargetType="Button">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Setter Property="MinHeight" Value="23"/>
<Setter Property="MinWidth" Value="75"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border
x:Name="Border"
CornerRadius="2"
BorderThickness="1"
Background="{StaticResource NormalBrush}"
BorderBrush="{StaticResource NormalBorderBrush}">
<ContentPresenter
Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource DefaultedBorderBrush}" />
</Trigger>
<Trigger Property="IsDefaulted" Value="true">
<Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource DefaultedBorderBrush}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource DarkBrush}" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource PressedBrush}" />
<Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource PressedBorderBrush}" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" />
<Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource DisabledBorderBrush}" />
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>