Blog‎ > ‎

Silverlight Button Background

posted Jan 16, 2010, 12:22 PM by Rene Rasmussen   [ updated Feb 1, 2010, 12:18 PM ]
Have you ever been to a restaurant ordering a red steak from the menu, just to find out that you very well done (almost white) steak?
  
Well, that is how I felt when I ordered a silverlight button with red background.

I created a background like this

and it looks like this
<Canvas Height="50" Width="200" Margin="0,0,0,20">
    <Canvas.Background>
      <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
        <GradientStop Color="#FFB72020" Offset="0.539"/>
        <GradientStop Color="#FFFFDCDC"/>
        <GradientStop Color="#FF530000" Offset="1"/>
      </LinearGradientBrush>
    </Canvas.Background>
</Canvas>

but when I create a button with the same background
<Button Height="50" Width="200" Click="Button2_Click" x:Name="_button2">
    <Button.Background>
        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
            <GradientStop Color="#FFB72020" Offset="0.539"/>
            <GradientStop Color="#FFFFDCDC"/>
            <GradientStop Color="#FF530000" Offset="1"/>
        </LinearGradientBrush>
    </Button.Background>
    <TextBlock>Click Me</TextBlock>
</Button>
it looked like this
That was not the button background I ordered!

So I started digging...
The default button template for in Silverlight is defined as 
<ControlTemplate TargetType="controls:Button">
    <Grid>
        <!-- snipped the 36 lines of VisualStatManager here -->
        <Border x:Name="Background" CornerRadius="3" Background="White" 
                BorderThickness="{TemplateBinding BorderThickness}" 
                BorderBrush="{TemplateBinding BorderBrush}">
            <Grid Background="{TemplateBinding Background}"  Margin="1">
                <Border Opacity="0"  x:Name="BackgroundAnimation" 
                        Background="#FF448DCA" />
                <Rectangle x:Name="BackgroundGradient" >
                    <Rectangle.Fill>
                        <LinearGradientBrush StartPoint=".7,0" EndPoint=".7,1">
                            <GradientStop Color="#FFFFFFFF" Offset="0" />
                            <GradientStop Color="#F9FFFFFF" Offset="0.375" />
                            <GradientStop Color="#E5FFFFFF" Offset="0.625" />
                            <GradientStop Color="#C6FFFFFF" Offset="1" />
                        </LinearGradientBrush>
                    </Rectangle.Fill>
                </Rectangle>
            </Grid>
        </Border>
        <ContentPresenter x:Name="contentPresenter" 
            Content="{TemplateBinding Content}" 
            ContentTemplate="{TemplateBinding ContentTemplate}"
            VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
            Margin="{TemplateBinding Padding}"/>
        <Rectangle x:Name="DisabledVisualElement" RadiusX="3" RadiusY="3" 
                   Fill="#FFFFFFFF" Opacity="0" IsHitTestVisible="false" />
        <Rectangle x:Name="FocusVisualElement" RadiusX="2" RadiusY="2" 
                   Margin="1" Stroke="#FF6DBDD1" StrokeThickness="1" 
                   Opacity="0" IsHitTestVisible="false" />
    </Grid>
</ControlTemplate>
...so, the standard button template is using a rectangle which hide background defined on the button.

I created I quick fix (hiding the rectangle), now the background shines through.
  public color SlBackgroundButton : Button
  {
    public override void OnApplyTemplate()
    {
      base.OnApplyTemplate();

      Rectangle rect = GetTemplateChild("BackgroundGradient") as Rectangle;
      if (rect != null)
      {
        LinearGradientBrush lbrush = rect.Fill as LinearGradientBrush;
        if (lbrush != null && lbrush.GradientStops.Count > 3)
        {
          lbrush.GradientStops[0].Color = Colors.Transparent;
          lbrush.GradientStops[1].Color = Colors.Transparent;
          lbrush.GradientStops[2].Color = Colors.Transparent;
          lbrush.GradientStops[3].Color = Colors.Transparent;
        }
      }
    }
  }

The result is the button "Steak" :-) I ordered


Comments