I'm a rank beginner with WPF and I don't even know where to look to find the answer to this question. This XAML seems very straightforward to me:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Button>
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
<Button.Content>Test</Button.Content>
</Button>
</Grid>
</Page>
When I mouse over the button, IsMouseOver
changes to True
and the trigger makes background turns green. For an instant. Then it turns blue.
Even better: if I attach the same setter to the IsFocused
property, once I focus on the button the background color throbs between green and blue.
There's something, somewhere in the Button (I'm guessing it's in whatever default theme is being used under Vista) that is making it behave this way. I suspect that there's another property that the trigger needs to set. But what?
You need to change the Button
's Template
rather than its Style
. Built into the template is something called ButtonChrome, and that is what is causing the irritating blue focus effect. Here is a very simple re-templating of the Button
control, taken from the provided Simple Styles:
<Style TargetType="{x:Type Button}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="MinHeight" Value="23"/>
<Setter Property="MinWidth" Value="75"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border
x:Name="Border"
CornerRadius="2"
BorderThickness="1"
Background="#C0C0C0"
BorderBrush="#404040">
<ContentPresenter
Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter TargetName="Border" Property="BorderBrush" Value="#202020" />
</Trigger>
<Trigger Property="IsDefaulted" Value="true">
<Setter TargetName="Border" Property="BorderBrush" Value="#202020" />
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="#808080" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="Border" Property="Background" Value="#E0E0E0" />
<Setter TargetName="Border" Property="BorderBrush" Value="#606060" />
</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>
You can see that by re-templating the control, you can change its visual tree. The visual tree in this template is nothing more than a Border
that contains a ContentPresenter
(so you can see the content of the button). I have effectively removed the ButtonChrome from the visual tree this way.
Charlie's answer is good. I simply want to supplement with an explanation of what was going on, and a comment didn't seem the place.
The reason why it was green for an instant and then was blue is because the default theme's ControlTemplate
for Button
already had an IsMouseOver
Trigger
to change the background.
Then you added another in your Style
. This doesn't replace the existing one because you could have multiple Trigger
s on the same property and value that have very different Setter
s and do completely different things.
So it was trying to do both, and did the green one first.