Why does Button background change?

I'm starting out with WPF, and I don’t even know where to look for the answer to this question. This XAML seems very simple 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 click on the button, IsMouseOver changes to True , and the trigger makes the green background green. For a moment. Then it turns blue.

Even better: if I bind the same installer to the IsFocused property, as soon as I focus on the button, the background color will start between green and blue.

There is something, somewhere in Button (I assume that in any theme it is used by default under Vista), which makes it behave this way. I suspect that there is another property that the trigger should set. But what?

+4
source share
2 answers

You need to change Button Template , not Style . The ButtonChrome element is built into the template, and this is what causes the annoying blue focus effect. Here is a very simple redesign of the Button template, 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 changing the template of 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 contents of the button). I effectively removed ButtonChrome from the visual tree this way.

+22
source

Charlie answers well. I just want to supplement the explanation of what is happening, and the comment did not seem like a place.

The reason it was green for a moment and then was blue is because for the default theme, the ControlTemplate for Button already had IsMouseOver Trigger to change the background.

Then you added another to your Style . This does not replace the existing one, because you can have several Trigger for the same property and values ​​that have different Setter values ​​and do completely different things.

So, he tried to do both, and first made green.

+6
source

All Articles