Why is the fill of an Ellipse not applied when the Stretch property is set inside a VisualBrush?

734 views Asked by At

I'm working on a custom control and I have a VisualBrush with the Visual property as such:

<VisualBrush.Visual>
    <Grid>
        <Ellipse Stretch="Uniform" Stroke="OrangeRed" StrokeThickness="1">
            <Ellipse.Fill>
                <RadialGradientBrush GradientOrigin="0.5,0.5">
                    <GradientStop Color="Yellow" Offset="0" />
                    <GradientStop Color="Orange" Offset="1" />
                </RadialGradientBrush>
            </Ellipse.Fill>
        </Ellipse>
        <Ellipse  Stretch="Uniform">
            <Ellipse.Fill>
                <RadialGradientBrush GradientOrigin="0.5, 0.05" RadiusX=".7" RadiusY=".5" >
                    <GradientStop Color="White" Offset=".10" />
                    <GradientStop Color="Transparent" Offset="1" />
                </RadialGradientBrush>
            </Ellipse.Fill>
        </Ellipse>
    </Grid>
</VisualBrush.Visual>

When the Stretch property is set to Uniform instead of using the RadialGradientBrush I created, it somehow creates a SolidColorBrush using the Stroke color. However, when I explicitly set the Width and Height properties of the Ellipse instead of using the Stretch property, I get the gradient I expected.

Any ideas of what's going weird here?

EDIT: I just observed the behavior occurs when I enclose the Ellipse inside of a ViewBox.

1

There are 1 answers

1
Chris On BEST ANSWER

I'm not sure what you're using the ViewBox for in your above example, but I think some of the strange behaviour you're seeing is a result of not setting the size on the root element for your VisualBrush.

In the documentation for VisualBrush.Visual, there's a paragraph that mentions sizing (added emphasis):

When you define a new Visual for a VisualBrush and that Visual is a UIElement (such as a panel or control), the layout system runs on the UIElement and its child elements when the AutoLayoutContent property is set to true. However, the root UIElement is essentially isolated from the rest of the system; styles, storyboards, and external layout dictated by the parent where the brush is applied cannot permeate this boundary. Therefore, you should explicitly specify the size of the root UIElement, because its only parent is the VisualBrush and therefore it cannot automatically size itself to the area being painted. For more information about layout in Windows Presentation Foundation (WPF), see the Layout.

If I run your code above, my ellipse is completely filled with the stroke colour, presumably because the the layout is calculated with the smallest value for the ellipse, so the stroke is large enough to cover ellipse content/fill (which is then upscaled to the fill the viewport so it looks like the stroke is the fill colour).

If I give the root element some arbitrary size on which to base the layout <Grid Width="100" Height="100">...</grid> I start to see the stroke and fill colours, rendered with relative sizes.