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 love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With