Skip to main content

Microsoft Silverlight

Answered Question TemplateBinding of GradientStop ColorRSS Feed

(0)

agaac
agaac

Member

Member

20 points

10 Posts

TemplateBinding of GradientStop Color

Hi,

I have a templated MyButton control that uses gradients inside to achieve various effects. For simplicity, let's say the whole control template is just a circle with a gradient (by default, Blue -> Transparent). The MouseOver state animates the gradient to a different color (Grey -> Transparent), which returns back to the original gradient (Blue -> Transparent) in Normal state.

What I want to achieve is: I want to give the user the control over the gradient color (Blue). I don't want the user to mess up with the entire gradient, just let them define this single color. Let's say the user wants to set it to Red, and I want all transitions and effects to still work correctly.

1) Since Background property is a Brush, I defined an extra dependency property in my class, called Glow, of type Color:

 public class MyButton : Button
 {
        public Color Glow
        {
            get { return (Color) GetValue(GlowProperty); }
            set { SetValue(GlowProperty, value); }
        }

        public static readonly DependencyProperty GlowProperty =
            DependencyProperty.Register("Glow", typeof(Color), typeof(MyButton),
                                        new PropertyMetadata(Color.FromArgb(0xff, 0x00, 0x00, 0x88)));

        public MyButton()
        {
            this.DefaultStyleKey = typeof(MyButton);
        }
    }
 

2) Now, in theory, I should be able to use this value in my template:

<Style TargetType="local:MyButton">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:MyButton">
                    <Grid x:Name="LayoutRoot"              
                          Width="{TemplateBinding Width}"              
                          Height="{TemplateBinding Height}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal">
                                    <Storyboard>
                                        <!-- Return to original Glow color -->
                                        <ColorAnimation                     
                                            Storyboard.TargetName="Glow"                     
                                            Storyboard.TargetProperty="Shape.Fill.(GradientBrush.GradientStops)[0].Color"                     
                                            To="{TemplateBinding Glow}"                     
                                            Duration="0:0:0.2">                                         
                                        </ColorAnimation>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="MouseOver">
                                    <Storyboard>
                                        <!-- Temporarily change gradient to different color -->
                                        <ColorAnimation                    
                                            Storyboard.TargetName="Glow"                    
                                            Storyboard.TargetProperty="Shape.Fill.(GradientBrush.GradientStops)[0].Color"                    
                                            To="#00888888"                    
                                            Duration="0:0:0.2">                                            
                                        </ColorAnimation>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Ellipse Stretch="Fill">
                            <Ellipse.Fill>
                                <LinearGradientBrush StartPoint="0.5,1" EndPoint="0.5,0">
                                    <LinearGradientBrush.GradientStops>
                                        <GradientStop Color="#00FFFFFF" Offset="0"/>
                                        <GradientStop Color="{TemplateBinding Glow}" Offset="1"/>
                                    </LinearGradientBrush.GradientStops>
                                </LinearGradientBrush>
                            </Ellipse.Fill>
                        </Ellipse>
                        <ContentPresenter HorizontalAlignment="Center"                           
                                          VerticalAlignment="Center">                            
                        </ContentPresenter>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
 

But it doesn't work.. no error, just does nothing. I can change the Glow color to Red in the constructor, in OnApplyTemplate.. no result.

I heard binding to GradientStop is just not supported in SL (and it works in WPF). Anyone has any idea why it's not supported?

Anyone has any idea for a workaround?

I could simply set the gradient color to Glow in OnApplyTemplate.. but then I will have to also hardcode the behavior for the visual states and set up colors from code there as well.. which makes using templates pointless here if I have to hardcode colors.

A solution with giving the user access to the whole gradient is not good either - the transparency is used in combination with other template layers to create a very specific effect (not shown in the example). Setting the gradient to arbitrary values will destroy the whole effect.

Another solution I could think of is splitting the Ellipse to 2 layers: solid 1 color background (of type SolidColorBrush, bindable to a property set by user), and a White -> Transparent gradient on top of that. This will however make the template a bit complex (I use a number of gradients like these, splitting everything into 2 layers will make the XAML "heavy"). So I was thinking, maybe anyone has a better solution?

Thanks in advance

Agata

agaac
agaac

Member

Member

20 points

10 Posts

Answered Question

Re: TemplateBinding of GradientStop Color

As I figured out, this kind of binding is not supported by Silverlight, so I had to manually "bind" it in code :(

The explanation why, is here: http://blogs.msdn.com/nickkramer/archive/2006/08/18/705116.aspx

  • Unanswered Question
  • Answered Question
  • Announcement
Microsoft Communities