Search code examples
wpfcontroltemplates

Dont understand why the color binding varies between Fill and GradientStop


I'm trying to get to grips with ControlTemplates in WPF. I noticed that when you try to reference a templated parent's background color - the binding statement seems to be different for elipse Fill and elipse GradientStop. Can any one explain why this is.

This works...

<Ellipse RenderTransformOrigin=".5,.5"  Fill="{TemplateBinding Background}">

This works...

<GradientStop Offset="0" Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background.Color}"/>

This doesnt work - why is this?

<GradientStop Offset="0" Color="{TemplatedParent Background}"/>

This produces an error...

<GradientStop Offset="0" Color="{TemplatedParent Background.Color}"/>

This doesnt work...

<Ellipse RenderTransformOrigin=".5,.5"  Fill="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background.Color}">

The instance looks like this...

        <Button Template="{StaticResource buttonTemplate1}"
            Height="100" Width="100" FontSize="40" 
            Background="Violet" Foreground="Aquamarine"
            Padding="0" Margin="6">Button 5</Button>

Solution

  • As mentioned in comments, you need to distinguish between Brush and Color type properties.

    • Brush-typed properties are used by controls, and include Fill, Stroke, and Background.
    • The most common use of Color is as a component of a Brush, either the color of a SolidColorBrush, or the color of a GradientStop of a LinearGradientBrush.

    There are also some binding syntax errors in the examples you posted.


    This doesnt work - why is this?

    <GradientStop Offset="0" Color="{TemplatedParent Background}"/>
    

    That's not a valid binding syntax. But assuming you meant TemplateBinding Background, then it's still not valid, because the target Color is a different type than the source Background (Brush).


    This produces an error...

    <GradientStop Offset="0" Color="{TemplatedParent Background.Color}"/>
    

    Same issue as above, you mean TemplateBinding instead of TemplatedParent. And, I believe that in any case TemplateBinding won't work for a nested property. You would need to write:

    <GradientStop Offset="0" Color="{TemplateBinding 
                  RelativeSource={RelativeSource TemplatedParent}, Path=Background.Color}" />
    

    This doesnt work...

    <Ellipse RenderTransformOrigin=".5,.5"  Fill="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background.Color}">
    

    The syntax is correct here, but the types don't match -- the target is Brush, and the source is System.Color.