tags:

views:

4375

answers:

4

No matter what I change the Background property to in a button it hardly changes, what am I supposed to do if I want a completely different colored button?

I know I can do this via editing a template of a button, but this seems like overkill.

A: 

I am not quite sure what do you mean by "button hardly changes" but when I write <Button x:Name="button" Background="Gold" Foreground="Red" Content="Hello!" /> I get a golden button with red text. If you want to edit the button even more (change how it looks when you click on it etc.) then you still have to use templates and visual state manager. I found two pretty good tutorials that specifically concentrate on the visual aspects of a Silverlight button: http://mattberseth.com/blog/2008/03/creating_a_custom_skin_for_sil.html and http://weblogs.asp.net/dwahlin/archive/2008/11/23/using-the-visual-state-manager-in-silverlight-templates.aspx

texmex5
A: 

I have the same problem. When I create a button it's light colored background and setting the background color makes no difference. Only change the opacitymask to 0 makes the button black, but then the text disappears as well.

A: 

I have the same problem. I would further describe "hardly changes" as it appears the default Aero theme is being multiplied by the custom button settings such as background. When I write the foreground changes as expected but the background does not appear like a solid brush color, rather it appears like the standard silver aero button theme colors underlaying a barely visible hint of gold that blends on top of it. I have tried several color combinations including a custom solidbrush applied and the same type of barely noticeable change applies.

+1  A: 

This looks like an issue with SilverLight 2.0 and the default ContentTemplate for a Button. I took a look at the source:

<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>

The issue is the Rectangle with it's own Background is on top of the Grid which has the Background you've set. (Also, the Border is hard-coded to White). We can fix this using our own ContentTemplate, but that means also adding all the VisualStatManager stuff to get all the animations that go along with the Button.

A second method is to subclass Button, and modify the template in the OnApplyTemplate override. Here is an example that lowers the opacity of the stock Button so the background shows through:

public class BKButton : Button {

public override void OnApplyTemplate() {
    base.OnApplyTemplate();

    Border border = GetTemplateChild("Background") as Border;
    Rectangle rect = GetTemplateChild("BackgroundGradient") as Rectangle;

    if(border != null) {
        border.Background = this.Background;
        border.Opacity = .6;
    }
    if (rect != null) {
        LinearGradientBrush lbrush = rect.Fill as LinearGradientBrush;
        if (lbrush != null) {
            lbrush.Opacity = .6;
        }
    }
}
ViNull
ViNull, your solution worked perfect! Now I am able to change backgroud color of button. The only issue I am facing now is the color doesnt change until mouse is removed from button. I want to change the color even when mouse hovers over button. Could you provide workaround for this?Thanks in advance.
Manoj
You'll need to override the mouse states of the VisualStateManager - if you need more custom changes that just tweaking the background, it's worth it to just go ahead and provide your own ControlTemplate
ViNull