Phil Jollans
Phil Jollans

Reputation: 3759

How to clip a line to an ellipse in XAML

I have defined two concentric circles and two diagonal lines, which I want to clip to one of the circles.

I have written the following XAML and my problem is that I do not understand its behavior.

    <Canvas>

      <Ellipse x:Name="OuterCircle" Width="200" Height="200" StrokeThickness="2" Stroke="Black">

        <Ellipse.Fill>
          <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
            <GradientStop Color="#FFCBCFD5" Offset="1"/>
            <GradientStop Color="#FFF5F6F7" Offset="0"/>
          </LinearGradientBrush>
        </Ellipse.Fill>

      </Ellipse>

      <Ellipse x:Name="InnerCircle" Width="184" Height="184" Margin="8" >

        <Ellipse.Fill>
          <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
            <GradientStop Color="#FFCBCFD5" Offset="0"/>
            <GradientStop Color="#FFF5F6F7" Offset="1"/>
          </LinearGradientBrush>
        </Ellipse.Fill>

      </Ellipse>

      <!-- In my opinion the lines are clipped to the wrong circle -->
      <Line X1="0" X2="200" Y1="0" Y2="200" Stroke="Black" StrokeThickness="2">
        <Line.OpacityMask>
          <VisualBrush Visual="{Binding ElementName=InnerCircle}" />
        </Line.OpacityMask>
      </Line>
      <Line X1="0" X2="200" Y1="200" Y2="2" Stroke="Black" StrokeThickness="2">
        <Line.OpacityMask>
          <VisualBrush Visual="{Binding ElementName=InnerCircle}" />
        </Line.OpacityMask>
      </Line>

    </Canvas>

  </Grid>
</Window>

This appears as follows:

enter image description here

The diagonal lines are clearly clipped to the outer circle.

In the XAML they are specifically clipped to the inner circle using ElementName=InnerCircle.

Why is that?

UPDATE

Using Stretch="None" as suggested by Clemens

<Line X1="0" X2="200" Y1="0" Y2="200" Stroke="Black" StrokeThickness="2">
  <Line.OpacityMask>
    <VisualBrush Visual="{Binding ElementName=InnerCircle}" Stretch="None"/>
  </Line.OpacityMask>
</Line>
<Line X1="0" X2="200" Y1="200" Y2="2" Stroke="Black" StrokeThickness="2">
  <Line.OpacityMask>
    <VisualBrush Visual="{Binding ElementName=InnerCircle}" Stretch="None"/>
  </Line.OpacityMask>
</Line>

produces exactly the result I had expected.

enter image description here

Using Clip did not work as I expected

<Line X1="0" X2="200" Y1="0" Y2="200" Stroke="Black" StrokeThickness="2" Clip="{Binding ElementName=InnerCircle, Path=RenderedGeometry}"/>
<Line X1="0" X2="200" Y1="200" Y2="2" Stroke="Black" StrokeThickness="2" Clip="{Binding ElementName=InnerCircle, Path=RenderedGeometry}"/>

In the designer, it looked like this

enter image description here

Clearly the margin on the inner circle has not been accounted for. (If I set the margin to 0, the circles are not concentric, but the clipping is correct.)

Weirdly, when I start the application, the diagonal lines do not appear at all.

Upvotes: 0

Views: 247

Answers (1)

Clemens
Clemens

Reputation: 128061

Brushes are stretched by default. Set Stretch to None:

<VisualBrush Visual="{Binding ElementName=InnerCircle}" Stretch="None"/>

Alternatively, you can also clip the Lines by the geometry of the Ellipse:

<Line ... Clip="{Binding ElementName=InnerCircle, Path=RenderedGeometry}"/>

Upvotes: 2

Related Questions