Trigger won't change Background - wpf

I'm trying to create a template for buttons in order to prevent the graying of the control when it is disabled, it is working just fine, but for some reason it won't change Backgrounds once I set a colour for it the Button Properties.
Here is the button I made:
<Style TargetType="Button" x:Key="TestButton">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="MinHeight" Value="29px" />
<Setter Property="MinWidth" Value="103px" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Background" Value="#EEEEEE"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border TextBlock.Foreground="{TemplateBinding Foreground}" x:Name="Border">
<Border.Background>
<SolidColorBrush Color="{TemplateBinding Background}" />
</Border.Background>
<Border.BorderBrush>
<SolidColorBrush Color="Black" />
</Border.BorderBrush>
<Border.BorderThickness>
<Thickness Top="0.75" Bottom="0.75" Right="0.75" Left="0.75"/>
</Border.BorderThickness>
<Border.CornerRadius>
<CornerRadius TopLeft="3" TopRight="3" BottomLeft="3" BottomRight="3"/>
</Border.CornerRadius>
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</Border>
<!--Triggers-->
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#E1F3FD" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#C4E9FF" />
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect Color="Black" Direction="500" ShadowDepth="1" BlurRadius="5" Opacity="0.5" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background" Value="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Background}"/>
<Setter Property="Opacity" Value="0.5" />
</Trigger>
<Trigger Property="IsEnabled" Value="True" >
<Setter TargetName="Border" Property="Background" Value="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Background}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
When I call it gives me two diferent results, the one that works is the following:
<Button Style="{DynamicResource ResourceKey=TestButton}" Content="Button" Height="66" Name="button1" Width="149" Click="button1_Click" />
But when I add a Background to it, it stops changing Backgrounds for some reason:
<Button Style="{DynamicResource ResourceKey=TestButton}" Background="Orange" Content="Button" Height="66" Name="button1" Width="149" Click="button1_Click" />

It wont change the color because you "overlay" the color with the color you defined in MainWindow.xaml.
Its called dependency property value precedence.
To read more about it take a look at this:
http://msdn.microsoft.com/en-us/library/ms743230.aspx
What happens in your case is that you defined a background in style and in trigger but then you set the value in MainWindow. The value set in MainWindow is considered the local value and the ones set in style are "style - values".
If you take a look at the link I gave you you will see that local value comes first before "style - values".
Local values are very powerful.
That is why your Button will always be Orange even when disabled. The property system will try to find a value for the background when your trigger fires and it will always find the local one because that is the value with the highest prority.
In order to make this work properly you will have to use SetCurrentValue instead of SetValue when setting the value of Button's background. (Means you will have to override Buttons code)
Take a look at this:
http://msdn.microsoft.com/en-us/library/system.windows.dependencyobject.setcurrentvalue.aspx
This method is used by a component that programmatically sets the value of one of its own properties without disabling an application's declared use of the property. The SetCurrentValue method changes the effective value of the property, but existing triggers, data bindings, and styles will continue to work.
Edit:
Example to understand dependency property value precedence and hit testing.
<Window.Resources>
<Style TargetType="{x:Type Grid}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Yellow" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<TextBlock Height="20" Margin="40" Text="asdfasdfa" VerticalAlignment="Bottom"/>
<Rectangle Height="100" VerticalAlignment="Bottom" >
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Offset="0"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Grid>

If you look at DependecyProperty value precedence order you will see that setting a value explicitly (treated as local value) on a control will override any values set by the trigger.

Just a note: the Background property is of type Brush, so you should write
<Border Background="{TemplateBinding Background}" ...>
...
</Border>
instead of
<Border ...>
<Border.Background>
<SolidColorBrush Color="{TemplateBinding Background}" />
</Border.Background>
...
</Border>

Related

WPF Textbox Template assistance

I am working on setting up a template for a textbox - and I am running into an issue with setting up the style for the box and am hoping for some assistance. Here is what I have so far:
---
<Window.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBoxBase}">
<Border x:Name="Border">
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border">
<Setter.Value>
<Border BorderThickness="1" BorderBrush="Black" CornerRadius="0">
<Border.Background>
<RadialGradientBrush GradientOrigin="0.225,-0.616" RadiusY="0.863" RadiusX="0.757">
<GradientStop Color="#EEFFFFFF"/>
<GradientStop Color="#00FFFFFF" Offset="0.696"/>
</RadialGradientBrush>
</Border.Background>
</Border>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="False">
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
---
When I try to compile this, I get a message stating:
Severity Code Description Project File Line Suppression State
Error MC3000 'The 'Setter' start tag on line 22 position 34 does not match the end tag of 'Trigger'. Line 35, position 31.' XML is not valid.
Anyone have any idea on what I missed here or am doing wrong? I think that I have closed all of the lines correctly.
The setter isn't working quite how you think it is. You're currently creating a border in your template and giving it an x:Name="Border", but then trying to overwrite it in the trigger, with the assumption that it will replace the existing border altogether:
<Setter TargetName="Border">
<Setter.Value>
<Border BorderThickness="1" BorderBrush="Black" CornerRadius="0">
That's not how setters work. Setters need three things:
A reference to an object that you want to modify (although in some cases this is implied).
The name of a property of that object that you wish to modify.
The new value for that property.
You're only providing 1 and 3, hence the error. Instead of trying to replace the border you have to instead modify the properties of the existing border:
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="BorderThickness" Value="1" />
<Setter TargetName="Border" Property="BorderBrush" Value="Black" />
<Setter TargetName="Border" Property="CornerRadius" Value="0" />
<Setter TargetName="Border" Property="Background">
<Setter.Value>
<RadialGradientBrush GradientOrigin="0.225,-0.616" RadiusY="0.863" RadiusX="0.757">
<GradientStop Color="#EEFFFFFF"/>
<GradientStop Color="#00FFFFFF" Offset="0.696"/>
</RadialGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
In practice you'd typically wrap all these up in their own style and apply that instead to keep the code clean, but that's an implementation detail.
If you really do want to replace the actual border object then there are ways to do it (e.g. by changing the template itself), but in most cases the above should suffice.

WPF - Content Presenter

I have created a resource dictionary for Button style and assigned it to a Button. The style appears in the button but I am not able to get the button text displayed. I have tried adding a content presenter but it didn't work. Please help.
<Button x:Name ="Submit" HorizontalAlignment="Left" Margin="346,186,0,0"
VerticalAlignment="Top" Width="75" Style="{DynamicResource
ResourceKey=ButtonStyle}" Height="50">
<ContentPresenter Name="MyContent">
<ContentPresenter.Content>
<Label>Click Me</Label>
</ContentPresenter.Content>
</ContentPresenter>
</Button>
The style for button is as follows..It is created using Blend..
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<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="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Rectangle Margin="0,8,0,0" VerticalAlignment="Stretch" Stroke="#FF000000" RadiusX="23.489" RadiusY="23.489">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF000000" Offset="0"/>
<GradientStop Color="#FFDE9090" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true"/>
<Trigger Property="ToggleButton.IsChecked" Value="true"/>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I also tried Button.Content> Click Button.Content> but not working.. Please suggest
Your button's ControlTemplate in Style missing a ContentPresenter to render the Content.
Add a ContentPresenter to the button's ControlTemplate. The resulting XAML for ControlTemplate would look like:
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Rectangle Margin="0,8,0,0" VerticalAlignment="Stretch" Stroke="#FF000000" RadiusX="23.489" RadiusY="23.489">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF000000" Offset="0"/>
<GradientStop Color="#FFDE9090" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true"/>
<Trigger Property="ToggleButton.IsChecked" Value="true"/>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Also, like I said in my comment, you do not need a ContentPresenter in the XAML for Button itself. You could simply have your content between and tags.
<Button
x:Name="Submit"
Width="75"
Height="50"
HorizontalAlignment="Left"
Margin="346,186,0,0"
VerticalAlignment="Top"
Style="{DynamicResource ResourceKey=ButtonStyle}">
Click Me
</Button>
Read this MSDN page for more information on ControlTemplate.

WPF TabItem and TabControl templates combined

I'm trying to make template for TabControl
visual design should be following:
TabControl content area should have small shadow over TabItems
but shadow should not be applied to active tab item
problem is that I can only write these templates as separated styles
meaning that if I use grid they'll end up in different grids and I can't change Zindex to make only one TabItem pop out over shadow
I'm using Border to apply shadow
<Border BorderThickness="0" >
<Border.Effect>
<DropShadowEffect Direction="90" ShadowDepth="1" Color="#b6b6b6" />
</Border.Effect>
</Border>
I came up with this, using the Kaxaml template for a TabControl, it incorporates Adrian's idea of using a LinearGradientBrush to simulate the shadow, I'm using a ControlTemplate:
<TabControl>
<TabControl.Resources>
<LinearGradientBrush x:Key="myBrush" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#ffffff" Offset="0.0"/>
<GradientStop Color="#eeeeee" Offset="0.46"/>
<GradientStop Color="#787878" Offset="1"/>
</LinearGradientBrush>
<Style TargetType="{x:Type TabControl}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid KeyboardNavigation.TabNavigation="Local">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TabPanel Name="HeaderPanel" Grid.Row="0" Panel.ZIndex="1" Margin="0,0,0,-1" IsItemsHost="True"
KeyboardNavigation.TabIndex="1" Background="{StaticResource myBrush}" />
<Border Name="Border" Grid.Row="1" Background="#FFFFFF" BorderBrush="#888888" BorderThickness="1"
KeyboardNavigation.TabNavigation="Local" KeyboardNavigation.DirectionalNavigation="Contained" KeyboardNavigation.TabIndex="2" >
<ContentPresenter Name="PART_SelectedContentHost" Margin="4" ContentSource="SelectedContent" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="#888888" />
<Setter TargetName="Border" Property="BorderBrush" Value="#AAAAAA" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- SimpleStyles: TabItem -->
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border Name="Border" Margin="0,0,-4,0" Background="#E0E0E0" BorderBrush="#888888" BorderThickness="1,1,1,1" >
<ContentPresenter x:Name="ContentSite" VerticalAlignment="Center" HorizontalAlignment="Center"
ContentSource="Header" Margin="12,2,12,2" RecognizesAccessKey="True"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Panel.ZIndex" Value="100" />
<Setter TargetName="Border" Property="BorderThickness" Value="1,1,1,0" />
<Setter TargetName="Border" Property="Background" Value="{StaticResource myBrush}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="#EEEEEE" />
<Setter TargetName="Border" Property="BorderBrush" Value="#AAAAAA" />
<Setter Property="Foreground" Value="#888888" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
<TabItem Header="Test" />
<TabItem Header="Test2" />
<TabItem Header="Test3" />
<TabItem Header="Test4" />
</TabControl>
By way of an explanation.
The LinearGradientBrush myBrush will be used in two places, the first is in the TabControl, as the Background:
<TabPanel Name="HeaderPanel" Grid.Row="0" Panel.ZIndex="1" Margin="0,0,0,-1" IsItemsHost="True"
KeyboardNavigation.TabIndex="1" Background="{StaticResource myBrush}" />
The Second is within the TabItem template as the background for all items that aren't selected *using a trigger); you could add additional selected styles if required:
<Setter TargetName="Border" Property="Background" Value="{StaticResource myBrush}" />
Note: I've changed the background of the TabControl so it's no longer transparent (so it has the shadow. This might fall flat on it's face depending on how you want to use the control (i.e. if you want to show content underneath).
Before this version, I had a different version that used a DropShadow and a clipping grid, which will retain the underlying transparency if you need it. It does rely on you manually matching the gradient brush with the DropShadow. Let me know if you need that other version and I'll post it.
Good luck.
You could get something similar by changing the background color to a gradient on the TabItem:
<Style TargetType="TabItem">
<Style.Triggers>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#eeeeee" Offset="0.0"/>
<GradientStop Color="#eeeeee" Offset="0.6"/>
<GradientStop Color="#b6b6b6" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>

Bind template data field to instance (via "Use a custom path expression"?)

I have created a template of a button, which contains an Image and a TextBlock. Since I would like to change the appearance of both, I think they need to be in the Template. But, of course, not every instance of this template should present the same text and image.
Until now, i found a promising property called "Use a custom path expression" at the "Text" / "Source"-value filed of the TextBlock / Image at:
Data Binding... > Element Property > Use a custom path expression
I would now like to set this value at the instances of the button. I already tried to manually insert a myText="Lorem Ipsum" in the XAML of the Button, but that does not seem to work.
Thank you in advance for your help!
Update: This is, how the XAML looks like:
<TextBlock [...] Text="{Binding myText, ElementName={x:Null}, FallbackValue=Lorem}"/>
How do I access this or modify this, so it can be accessed?
Update 2: There already exist bindings for the TextBlock and the Image. At the moment, the XAML of the Button looks like that:
<s:SurfaceButton Command="{Binding SearchCustomCommand}" Style="{DynamicResource BasicButton}">
<StackPanel Orientation="Vertical" Height="60" Width="48" IsHitTestVisible="False">
<Image Source="{StaticResource ImageSourceToolboxSearchIcon}"
[...]
Stretch="Uniform" />
<TextBlock Text="{lex:LocText ToolboxButtonSearchesCustom}"
FontFamily="{DynamicResource button.font}"
[...]
FontSize="{DynamicResource button.size}"
Foreground="{DynamicResource button.color.default}"/>
</StackPanel>
</s:SurfaceButton>
I would now like to extract the Image and Textbox to the template (which also already exists), so I could refrence the Button in a way like this (whith all the Information about sizes and colors etc in the template and only the reference to the resource in the actual instance of the button - to be able to change the image/text for echt button seperately):
<s:SurfaceButton
Command="{Binding SearchPopularCommand}"
Style="{DynamicResource ToolboxButtonBig}"
ImageSource="{StaticResource ImageSourceToolboxSearchIcon}"
TextBlockSource="{lex:LocText ToolboxButtonSearchesCustom}"/>
I already copied the whole XAML for the StackPanel and the included TextBlock and Image to the Template. Now those are shown on every Button (which is fine), but i can't change the contents of them.
I'm sorry if the description is quite poor - I'm rather new to WPF...
Update 3: After some further research, I found questions similar to mine - which obviously describe the problem better than I could:
Button template with image and text in wpf
Creating an image+text button with a control template?
it is not necessary to edit button's template to insert image and text, you can set Button.Content property like this:
<Button>
<Button.Content>
<StackPanel Orientation="Horizontal">
<Image Source="../Images/image.png"/>
<TextBlock Text="Lorem Ipsum"/>
</StackPanel>
</Button.Content>
</Button>
and it will work well. example above can be simplified but I inserted it like this for better understanding what is going on.
EDIT:
here are examples how it can be done in two different ways:
overwriting template:
<Button Content="Lorem Ipsum">
<Button.Template>
<ControlTemplate TargetType="Button">
<StackPanel Orientation="Horizontal">
<Image x:Name="ButtonImage" Source="../Images/mouseNotOverImage.png"/>
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="ButtonImage" Property="Source" Value="../Images/mouseOverImage.png"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
complete button template definition you can find here
modifying style:
<Button>
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Horizontal">
<Image Source="../Images/mouseOverImage.png"/>
<TextBlock Text="Lorem Ipsum"/>
</StackPanel>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Horizontal">
<Image Source="../Images/mouseNotOverImage.png"/>
<TextBlock Text="Lorem Ipsum"/>
</StackPanel>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Your first option would be to define a style (or styles), e.g.
<Window.Resources>
<Style x:Key="MyButton" TargetType="{x:Type Button}" >
<Setter Property="Content">
<Setter.Value>
<Grid>
<Image .../>
<TextBlock Text="Test"/>
</Grid>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Button Style="{StaticResource MyButton}" />
</Grid>
Your second option would be to use Blend to make a copy of the default button style and edit that
<Window.Resources>
<Style x:Key="MyButton" TargetType="{x:Type Button}" >
<Setter Property="Content">
<Setter.Value>
<Grid>
<TextBlock Text="Test"/>
</Grid>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<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>
<SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070"/>
<Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<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="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Themes:ButtonChrome x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" RenderDefaulted="{TemplateBinding IsDefaulted}" SnapsToDevicePixels="true">
<!-- put your text and image here -->
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Themes:ButtonChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="RenderDefaulted" TargetName="Chrome" Value="true"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="true">
<Setter Property="RenderPressed" TargetName="Chrome" Value="true"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Button Content="Button" HorizontalAlignment="Left" Margin="167,151,0,0" VerticalAlignment="Top" Width="75" Style="{DynamicResource MyButtonStyle}"/>
</Grid>
and a third option would be to create a custom control based on the default button style. You could then create dependency properties and use template bindings.

Using WPF, what is the best method to update the background for a custom button control?

In WPF, we are creating custom controls that inherit from button with completely drawn-from-scratch xaml graphics. We have a border around the entire button xaml and we'd like to use that as the location for updating the background when MouseOver=True in a trigger. What we need to know is how do we update the background of the border in this button with a gradient when the mouse hovers over it?
In your ControlTemplate, give the Border a Name and you can then reference that part of its visual tree in the triggers. Here's a very brief example of restyling a normal Button:
<Style
TargetType="{x:Type Button}">
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="customBorder"
CornerRadius="5"
BorderThickness="1"
BorderBrush="Black"
Background="{StaticResource normalButtonBG}">
<ContentPresenter
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger
Property="IsMouseOver"
Value="True">
<Setter
TargetName="customBorder"
Property="Background"
Value="{StaticResource hoverButtonBG}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
If that doesn't help, we'll need to know more, probably seeing your own XAML. Your description doesn't make it very clear to me what your actual visual tree is.
You would want to add a trigger like this...
Make a style like this:
<Style x:Key="ButtonTemplate"
TargetType="{x:Type Button}">
<Setter Property="Foreground"
Value="{StaticResource ButtonForeground}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="{x:Type Button}">
<Grid
SnapsToDevicePixels="True"
Margin="0,0,0,0">
<Border Height="20"
x:Name="ButtonBorder"
BorderBrush="{DynamicResource BlackBorderBrush}">
<TextBlock x:Name="button"
TextWrapping="Wrap"
Text="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}"
SnapsToDevicePixels="True"
Foreground="#FFFFFFFF"
Margin="6,0,0,0"
VerticalAlignment="Center"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<!-- Disabled -->
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="ButtonBorder"
Property="Background"
Value="{DynamicResource ButtonBackgroundMouseOver}" />
<Setter TargetName="ButtonBorder"
Property="BorderBrush"
Value="{DynamicResource ButtonBorderMouseOver}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then add some resources for the gradients, like this:
<LinearGradientBrush x:Key="ButtonBackgroundMouseOver"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="#FF000000"
Offset="0.432"/>
<GradientStop Color="#FF808080"
Offset="0.9"/>
<GradientStop Color="#FF848484"
Offset="0.044"/>
<GradientStop Color="#FF787878"
Offset="0.308"/>
<GradientStop Color="#FF212121"
Offset="0.676"/>
</LinearGradientBrush>
Please let me know if you need more help with this.

Resources