How to build a button style based on another in WPF - wpf

I'm new to WPF and by following a quick tutorial I succeeded on getting a personalized button style as the following one:
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border>
<Rectangle Margin="2" StrokeThickness="1" Stroke="#60000000" StrokeDashArray="1 2"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="NormalBrush" Color="#FF0C0C13"/>
<SolidColorBrush x:Key="LightBrush" Color="#FF2E2E3E"/>
<SolidColorBrush x:Key="PressedBrush" Color="#FF209FD4"/>
<SolidColorBrush x:Key="DisabledForegroundBrush" Color="#FF494968" />
<SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#FF2E2E3E" />
<SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF" />
<SolidColorBrush x:Key="SelectedBackgroundBrush" Color="#DDD" />
<SolidColorBrush x:Key="HorizontalNormalBrush" Color="AntiqueWhite"/>
<SolidColorBrush x:Key="HorizontalLightBrush" Color="AntiqueWhite"/>
<SolidColorBrush x:Key="DarkBrush" Color="AntiqueWhite"/>
<SolidColorBrush x:Key="NormalBorderBrush" Color="Aqua"/>
<Style x:Key="MyButtonStyle" TargetType="Button">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="Border" BorderThickness="1" Background="{StaticResource NormalBrush}" BorderBrush="#FF2E2E3E">
<ContentPresenter Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource LightBrush}" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource PressedBrush}" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" />
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
It seems indeed that we need to override the ControlTemplate and that to keep some functionalities (like the behaviour while hovering the mouse) we need to define them. What is already strange to me here, is that under ControlTemplate it is defined a Border tag and then the trigger refer to that Border. So as a first question, why Border and not something else?
But now the main question is: suppose I want exactly the same button, with the same colors and functionalities but without the borders. I tried to use the BasedOn similar to the following:
<Style x:Key="MyButtonStyleNoBorder" TargetType="{x:Type Button}" BasedOn="{StaticResource MyButtonStyle}">
<Setter Property="BorderThickness" Value="0"/>
</Style>
but no way. The only solution I found is to copy the entire code of MyButtonStyle and then to change only one character (!) to have BorderThickness="0". But this to me looks stupid. Can you please help?

So as a first question, why Border and not something else?
The element named Border is the outermost element and its child will inherit most of its state, in this case the background.
But now the main question is: suppose I want exactly the same button, with the same colors and functionalities but without the borders.
If you like a button without borders you can just set the BorderThickness property of the button to 0. directly or as a setter in the style.
The only solution I found is to copy the entire code of MyButtonStyle and then to change only one character (!) to have BorderThickness="0". But this to me looks stupid. Can you please help?
Styles are kind of a list for what property to change on a target. The basedOn functionality will use the basedOn-style and "add" the new setter from the new style.
A Template is more like a drawing (and some graphical behavior) of the control and when you specify a new one you just throw away the old one. I would be possible to do a basedOn there. How would we determine what to use and what to replace?
Not the answer you wished for but hopefully you got it anyway.
<Border x:Name="Border" BorderThickness="{TemplateBinding BorderThickness}" Background="{StaticResource NormalBrush}" BorderBrush="#FF2E2E3E">
<ContentPresenter Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True"/>
</Border>
Will pick up the value the Button object gets on BorderThickness.

I would have done this using MVVM (if you have not considering MVVM yet).
In my ViewModel bound to the Button, I would add a property "IsBorderLess".
Then, on the Triggers:
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsBorderLess}" Value="True">
<Setter TargetName="Border" Property="BorderThickness" Value="0"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsBorderLess}" Value="False">
<Setter TargetName="Border" Property="BorderThickness" Value="10"/>
</DataTrigger>
..........

Related

Change the background colour of a CheckBox using DataTriggers

I'd like the background of my CheckBox to change colour depending on if it matches a pre-defined bool (not just if it's Checked or Unchecked). The problem is that this looks poor if you do it to the CheckBox alone, so I've wrapped the CheckBox in a Grid and set the background of the Grid instead. My issue now is that I want to pull out this style so I can reuse it for my other Checkbox
Here is my XAML:
<Grid Margin="5 10 0 0">
<CheckBox Name="cbJimbo" Content="JIMBO" FontSize="12"
IsChecked="{Binding MyObject.Jimbo}"
Style="{StaticResource CheckBoxStyle}"/>
<Grid.Style>
<Style TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=cbJimbo, Path=Background}" Value="Yellow">
<Setter Property="Background" Value="Yellow" />
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
</Grid>
What is the best way to refactor this?
In the interest of completeness (Although not entirely relevant) here is the CheckBox style, which determines if the CheckBox matches the default value and then sets the CheckBox background in a too subtle fashion. Also relevant as my Grid is currently bound to the background of this Checkbox:
<Style x:Key="ValidationCheckBox" TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<StackPanel>
<AdornedElementPlaceholder x:Name="placeholder"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)/ErrorContent.ErrorType}" Value="{x:Static wrapper:ErrorTypeEnum.Default}">
<Setter Property="Background" Value="Yellow"/>
</DataTrigger>
</Style.Triggers>
</Style>
Making Your Style Reusable
If you want create a separate style for the Grid, the element name binding is problematic, since the same name might already exist in this namescope. An alternative, although not very robust is to explicitly specify the child that the CheckBox is via index. It is advisible to trigger on the real property that triggers the CheckBox, too, so you do not have to change the brush to in both style. It also makes the reason for the color change apparent.
<Style TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Children[0].(CheckBox.Background)}" Value="Yellow">
<Setter Property="Background" Value="Yellow" />
</DataTrigger>
</Style.Triggers>
</Style>
Changing the Control Template
As you might know, the visual appearance and states of a control are defined in a ControlTemplate. Instead of building a Grid around the CheckBox, you could extract its default styleand control template and adapt it, so that it has the same backgroud as the check mark box. There is already a Grid as template root, but its background is set to Transparent. If we replace that with a TemplateBinding to the Background property, it looks as expected.
<Grid x:Name="templateRoot" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
This is the whole and adapted control template for CheckBox.
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="OptionMarkFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="14,0,0,0" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="OptionMark.Static.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="OptionMark.Static.Border" Color="#FF707070"/>
<SolidColorBrush x:Key="OptionMark.Static.Glyph" Color="#FF212121"/>
<SolidColorBrush x:Key="OptionMark.MouseOver.Background" Color="#FFF3F9FF"/>
<SolidColorBrush x:Key="OptionMark.MouseOver.Border" Color="#FF5593FF"/>
<SolidColorBrush x:Key="OptionMark.MouseOver.Glyph" Color="#FF212121"/>
<SolidColorBrush x:Key="OptionMark.Pressed.Background" Color="#FFD9ECFF"/>
<SolidColorBrush x:Key="OptionMark.Pressed.Border" Color="#FF3C77DD"/>
<SolidColorBrush x:Key="OptionMark.Pressed.Glyph" Color="#FF212121"/>
<SolidColorBrush x:Key="OptionMark.Disabled.Background" Color="#FFE6E6E6"/>
<SolidColorBrush x:Key="OptionMark.Disabled.Border" Color="#FFBCBCBC"/>
<SolidColorBrush x:Key="OptionMark.Disabled.Glyph" Color="#FF707070"/>
<Style x:Key="CheckBoxStyle" TargetType="{x:Type CheckBox}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource OptionMark.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource OptionMark.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid x:Name="templateRoot" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border x:Name="checkBoxBorder" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Grid x:Name="markGrid">
<Path x:Name="optionMark" Data="F1 M 9.97498,1.22334L 4.6983,9.09834L 4.52164,9.09834L 0,5.19331L 1.27664,3.52165L 4.255,6.08833L 8.33331,1.52588e-005L 9.97498,1.22334 Z " Fill="{StaticResource OptionMark.Static.Glyph}" Margin="1" Opacity="0" Stretch="None"/>
<Rectangle x:Name="indeterminateMark" Fill="{StaticResource OptionMark.Static.Glyph}" Margin="2" Opacity="0"/>
</Grid>
</Border>
<ContentPresenter x:Name="contentPresenter" Grid.Column="1" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasContent" Value="true">
<Setter Property="FocusVisualStyle" Value="{StaticResource OptionMarkFocusVisual}"/>
<Setter Property="Padding" Value="4,-1,0,0"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.MouseOver.Border}"/>
<Setter Property="Fill" TargetName="optionMark" Value="{StaticResource OptionMark.MouseOver.Glyph}"/>
<Setter Property="Fill" TargetName="indeterminateMark" Value="{StaticResource OptionMark.MouseOver.Glyph}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Disabled.Border}"/>
<Setter Property="Fill" TargetName="optionMark" Value="{StaticResource OptionMark.Disabled.Glyph}"/>
<Setter Property="Fill" TargetName="indeterminateMark" Value="{StaticResource OptionMark.Disabled.Glyph}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Pressed.Border}"/>
<Setter Property="Fill" TargetName="optionMark" Value="{StaticResource OptionMark.Pressed.Glyph}"/>
<Setter Property="Fill" TargetName="indeterminateMark" Value="{StaticResource OptionMark.Pressed.Glyph}"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Opacity" TargetName="optionMark" Value="1"/>
<Setter Property="Opacity" TargetName="indeterminateMark" Value="0"/>
</Trigger>
<Trigger Property="IsChecked" Value="{x:Null}">
<Setter Property="Opacity" TargetName="optionMark" Value="0"/>
<Setter Property="Opacity" TargetName="indeterminateMark" Value="1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Creating Custom Controls
If you intend to use the same control hierarchy in the same way in multiple places, the original style will not save you from lots of code duplication that makes your code less maintainable. In such scenarios, consider creating a UserControl which encapsulates the control as single, reusable control instead.
The simplest way to create a control in WPF is to derive from UserControl. When you build a control that inherits from UserControl, you add existing components to the UserControl, name the components, and reference event handlers in WPF.
If built correctly, a UserControl can take advantage of the benefits of rich content, styles, and triggers. However, if your control inherits from UserControl, people who use your control will not be able to use a DataTemplate or ControlTemplate to customize its appearance.
If your control is not only a composition of other controls, but a fully-fledged new control with custom behavior and control template as well as theming support, you would create a custom control instead. For more information and differences refer to Control authoring overview.

WPF MenuItem border

Does anyone know how to remove that awful and annoying border that appears when you mouseover a menuitem in a menu.
I've messed around with styles and googled around but I can't wrap my head around it.
Example with a button in a menu;
You can find the default style and control template of the MenuItem class in this MSDN article.
The control which shows the border that is annoying you, is the control named "Border" whose background changes in the trigger for the property IsHighlighted.
This border is defined in the ControlTemplate with the key x:Key="{x:Static MenuItem.TopLevelItemTemplateKey}".
Removing the trigger (and for the sake of completeness the border) will let the MenuItem appear as you want it to.
Here is the original control template:
<ControlTemplate x:Key="{x:Static MenuItem.TopLevelItemTemplateKey}" TargetType="MenuItem">
<Border Name="Border">
<Grid>
<ContentPresenter Margin="6,3,6,3" ContentSource="Header" RecognizesAccessKey="True" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource NormalBrush}"/>
<Setter TargetName="Border" Property="BorderBrush" Value="Transparent"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
And this is the adjusted template:
<ControlTemplate x:Key="{x:Static MenuItem.TopLevelItemTemplateKey}" TargetType="MenuItem">
<Grid>
<ContentPresenter Margin="6,3,6,3" ContentSource="Header" RecognizesAccessKey="True" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

Base a ControlTemplate on another ControlTemplate

I know there must be an easy answer to this but I can't find it.
I've got a button style called HoverButton.
<Style x:Key="HoverButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border>
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="Background" Value="WhiteSmoke"/>
<Setter Property="Foreground" Value="DarkRed"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Background" Value="Transparent"/>
</Style>
I then want to create another 'derived' style that is based on a HoverButton with specific content. I've reduced the complexity of the above style here, but it's complex enough that I don't want to copy and paste it.
<Style x:Key="CloseButton" BasedOn="{StaticResource HoverButton}" TargetType="{x:Type Button}">
<Setter Property="Content">
<Setter.Value>
<Path Width="8" Height="8" Stroke="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType=Button}}" Data="M0,0 L8,8 M8,0 L0,8" StrokeThickness="2" />
</Setter.Value>
</Setter>
</Style>
This doesn't work - "Specified element is already the logical child of another element. Disconnect it first." It seems like I need to redefine the Template property of the derived style, but somehow reference the base style's template.
Any ideas?
You cannot base templates on one-another, but this error could easily be resolved. Just create an equivalent ContentTemplate instead of setting the Content. That way one Path is created for each button, and not one for all buttons (which is not allowed).

WPF: Trigger for ListBoxItem.IsSelected not working for Background property

I try to change the Background property for my ListBoxItems using triggers in the ItemContainerStyle of my ListBox as follows:
<ListBox Height="100" HorizontalAlignment="Left" Margin="107,59,0,0" Name="listBox1" VerticalAlignment="Top" Width="239">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Lightblue"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" Value="Red"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="Yellow"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.Items>
<ListBoxItem Content="First Item"/>
<ListBoxItem Content="SecondItem"/>
<ListBoxItem Content="Third Item"/>
</ListBox.Items>
</ListBox>
I would expect unselected items to have a light blue background, hovered items (i.e. when the mouse cursor is over them) to be yellow and selected items to be red.
For the unselected and hovered items this is working as expected, but the selected items still have their standard background color (i.e. blue, if the listbox has focus and light gray otherwise).
Is there anything I'm missing? Is this behaviour documented somewhere?
Thanks for any hint!
EDIT
I'm aware of the solution of overriding the default system colors (as described in Change selected and unfocused Listbox style to not be grayed out, thanks anyway for everyone posting this as an answer). However this is not what I want to do. I'm more interested in why my solution doesn't work.
I'm suspecting the standard ControlTemplate of ListItem to define it's own triggers which seem to take precendence over triggers defined by the style (perhaps someone could confirm this and point me to some resource where this behaviour is defined).
My solution for the meantime is to define a ControlTemplate for my ListItems like:
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border Name="Border" Padding="2" SnapsToDevicePixels="true" Background="LightBlue" Margin="0">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Border" Property="Background" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
A little bit of reflecting on the Aero-style offers us an explanation to why this simple trigger-setting doesn't work.
The ListBoxItem has a ControlTemplate with triggers that takes precedence over our trigger. At least this seems to be true for a MultiTrigger.
I´ve managed to override the simple trigger of Selected=true but for the multitrigger I had to make my own ControlTemplate.
This is the template from the Aero style that shows the problematic MultiTrigger:
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Bd" Value="{DynamicResource {x:Static HighlightBrush}}" Property="Background" />
<Setter Value="{DynamicResource {x:Static HighlightTextBrush}}" Property="Foreground" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true" />
<Condition Property="IsSelectionActive" Value="false" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Value="{DynamicResource {x:Static ControlBrush}}" Property="Background" />
<Setter Value="{DynamicResource {x:Static ControlTextBrush}}" Property="Foreground" />
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Value="{DynamicResource {x:Static GrayTextBrush}}" Property="Foreground" />
</Trigger>
</ControlTemplate.Triggers>
<Border Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
</ControlTemplate>
Hope it clears things up a little bit. I can't fathom why they´ve overcomplicated the style this much.
delete IsSelected trigger
And add to listbox:
<ListBox.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="Red" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}"
Color="Red" />
</ListBox.Resources>
First brush for focused second for otherwise
Try adding this to your window resources -
<Window.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="Red" />
</Window.Resources>
And remove the IsSelected Trigger from your code, it won't work because every system has its default highlight brush depending on your system theme.
You need to override the highlight brush in your code to make it work.
Try using Selector.IsSelected in your Trigger rather than IsSelected.

How are WPF Buttons and TextBlock styles related?

I have a custom style for my 'default' Buttons, and also created a custom style for TextBlocks. If I remove the TextBlock style entirely, everything works fine, but once the TextBlock styling is added in for some reason the Button style is used on the Button's text 'default' state. It seems like some kind of inheritance is going on here but I can't see where in the msdn docs. What's going on?
I'm using Expression Blend 4-- and also another odd thing is that the preview in Blend looks fine, but when I RUN the application, the button styles are incorrect in their default state. Here's the styles which seem to be conflicting:
<ResourceDictionary>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Foreground">
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="#FFFDFF00" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="RenderTransformOrigin" Value="0.5,0.5"/>
<Setter Property="RenderTransform">
<Setter.Value>
<TransformGroup>
<ScaleTransform ScaleY="1.20" ScaleX="1.20"/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<ContentPresenter RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<ContentPresenter.Effect>
<DropShadowEffect BlurRadius="3" ShadowDepth="4"/>
</ContentPresenter.Effect>
</ContentPresenter>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True"/>
<Trigger Property="IsDefaulted" Value="True"/>
<Trigger Property="IsMouseOver" Value="True"/>
<Trigger Property="IsPressed" Value="True"/>
<Trigger Property="IsEnabled" Value="False"/>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="FontFamily" Value="/Rtk;component/Fonts/#Segoe Print"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Background" Value="{x:Null}"/>
</Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextWrapping" Value="NoWrap"/>
<Setter Property="TextTrimming" Value="None"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect BlurRadius="3" ShadowDepth="4"/>
</Setter.Value>
</Setter>
<Setter Property="FontFamily" Value="/Rtk;component/Fonts/#Segoe Print"/>
</Style>
</ResourceDictionary>
This is how I am using the Button control itself:
<Button Content="Button Text" FontSize="24"/>
(note that this fontsize is different from the size I specified in the default style, 18 - I want to override it in this button's case)
Edit:
The actual button entry looks like this in MainWindow.xaml, there's no other customizations other than the style changes I posed from App.xaml:
<Button Content="Button" HorizontalAlignment="Left" Margin="336,0,0,274.226" VerticalAlignment="Bottom" Width="75"/>
To illustrate what I'm seeing:
Just a fast wild guess, but when the content of a button is a string, isn't it default a textblock?
As people have suggested, your Button contains a Textblock created to hold the content, it is picking up the style from app.xaml, you can work around this in a few ways, here are a couple:
Put an explicit textblock into your button, and apply no style:
<Button Margin="272,192,277,0" VerticalAlignment="Top">
<TextBlock Text="Button" Style="{x:Null}"/>
</Button>
Put a textblock into your button style, also with a null style:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<TextBlock Text="{TemplateBinding Content}" Style="{x:Null}">
<TextBlock.Effect>
<DropShadowEffect BlurRadius="3" ShadowDepth="4"/>
</TextBlock.Effect>
</TextBlock>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True"/>
<Trigger Property="IsDefaulted" Value="True"/>
<Trigger Property="IsMouseOver" Value="True"/>
<Trigger Property="IsPressed" Value="True"/>
<Trigger Property="IsEnabled" Value="False"/>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
Hopefully one of those 2 will work for you.
Looking only ay the code you posted, I can't see how the TextBlock Style would in any way influence the appearance of the Buttons - unless the Content of the Buttons consists (directly or indirectly) of TextBlocks. Can you post a more complete code sample, possibly including the Button's XAML?

Resources