Why does a button style behave this way?

Feb 19, 2009 at 7:41 PM
Edited Feb 19, 2009 at 7:58 PM
I ran into an interesting problem and I am not sure how to fix it. I need to change a button's text to be partially underlined if it meets certain criteria. We have a global style that is defined on the button with triggers that change the background and font if the button is disabled. I thought I could just change the content and the styles world be fine. No such luck. The style remained if I chnaged just the text as a string but if I inserted a TextBlock as the content the font style disappeared. Why is this happening? Also, any ideas on how to fix this?

here is the style we used

 

 

<Style TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{x:Null}" /> 
<Setter Property="Template"> 
<Setter.Value
<ControlTemplate TargetType="{x:Type Button}"> 
<Border x:Name="outerBorder" BorderThickness="1" Margin="0" BorderBrush="{StaticResource ButtonBorderBrush}" CornerRadius="4,4,4,4"> 
<Border.BitmapEffect
<OuterGlowBitmapEffect GlowSize="1" GlowColor="#FFC1D08E"/>
</Border.BitmapEffect>
<Border x:Name="innerBorder" BorderThickness="0" Margin="2" Background="{DynamicResource ButtonBackgroundBrush}" CornerRadius="2" Padding="3"> <Border.BitmapEffect>
<OuterGlowBitmapEffect GlowColor="{DynamicResource ButtonGlowColor}" GlowSize="2" Opacity="1" />
</Border.BitmapEffect>
<Grid
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="content" Style="{StaticResource ButtonTypeFace}" Margin="3,0,3,0" /> 
</Grid>
</Border
</Border
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="content" Property="Style" Value="{StaticResource ButtonDisabledFace}" />
<Setter Property="Background" TargetName="innerBorder" Value="#FFc6ccb7"/>
<Setter Property="BorderBrush" TargetName="outerBorder" Value="#FFc6ccb7"/> 
<Setter Property="Margin" TargetName="content" Value="3,0,3,0"/> 
<Setter Property="HorizontalAlignment" TargetName="content" Value="Center"/> 
<Setter Property="VerticalAlignment" TargetName="content" Value="Center"/> 
<Setter Property="BitmapEffect" TargetName="content"> 
<Setter.Value
<DropShadowBitmapEffect Color="#FFFFFFFF" ShadowDepth="1" Softness="0"/> 
</Setter.Value
</Setter
<Setter Property="BorderThickness" TargetName="outerBorder" Value="0.3,0.3,0.3,0.3"/> 
</Trigger
<Trigger Property="IsMouseOver" Value="true"> 
<Setter TargetName="innerBorder" Property="Background" Value="{StaticResource ButtonHighlightBrush}" /> 
<Setter Property="BitmapEffect" TargetName="outerBorder"> 
<Setter.Value
<OuterGlowBitmapEffect GlowColor="#FFC1D08E" GlowSize="2"/> 
</Setter.Value
</Setter
<Setter Property="BitmapEffect" TargetName="innerBorder">
<Setter.Value>
<OuterGlowBitmapEffect GlowColor="#FFC2CE97" GlowSize="2" Opacity="1"/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="innerBorder" Property="Background" Value="{StaticResource ButtonHighlightBrush}" />
<Setter Property="BitmapEffect" TargetName="outerBorder">
<Setter.Value>
<OuterGlowBitmapEffect GlowColor="#FFC1D08E" GlowSize="3"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

 

 

 

 

 

Coordinator
Feb 19, 2009 at 11:04 PM
The issue is with setting the Style of ContentPresenter instead of changing the properties of the Button. When the content is a string, the ContentPresenter will have a template that contains a TextBlock. In this setup, the TextBlock inherits from the ContentPresenter since it is in the template of the ContentPresenter. When you add your own TextBlock, the TextBlock becomes the logical child of the Button. In this setup, the TextBlock inherits from the Button and bypasses the Button's template elements.

If you were to leave off TargetName on the Setters and create some initial Setters for the Button instead of the ContentPresenter, then you should see your desired behavior.

Also, BitmapEffects have poor performance and are being depricated. I would suggest looking at the Effect property introduced in .NET 3.5 SP1.

Ben