StuartMorgan
StuartMorgan

Reputation: 678

WPF Line Issues

I'm trying to make a very simple red X button, similar to when you mouse over the X to close a Google Chrome tab. The Line control seems to respect its bounds on the bottom and right, but protrudes from them on the top and left, and I'm not sure how to go about fixing it (beyond giving them seemingly arbitrary margins to force them into submission)... I have the following XAML:

<Grid Background="Black">
    <Ellipse Height="15" Width="15" Fill="Red" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    <Line X1="0" Y1="0" X2="10" Y2="10" HorizontalAlignment="Center" VerticalAlignment="Center" Stroke="White" StrokeThickness="1" StrokeStartLineCap="Round" StrokeEndLineCap="Round"/>
    <Line X1="0" Y1="10" X2="10" Y2="0" HorizontalAlignment="Center" VerticalAlignment="Center" Stroke="White" StrokeThickness="1" StrokeStartLineCap="Round" StrokeEndLineCap="Round"/>
</Grid>

The first problem is with the line going from top-left to bottom-right: enter image description here

I selected the line to show the bounding box. Note how the line pokes out of the ellipse (and its bounding box) in the top-left but is inside it in the bottom-right. Shouldn't these act consistently, either both poking out or both staying within their boundaries?

The first line at least goes through the center of the corners of the bounding box, but the second line ends up getting shifted up and left:

enter image description here

They both appear to be respecting the bounds on the bottom and right, but protruding from the bounds on the top and left, which leads them to be off-center. Any ideas on what I can do to get them to act the way I want? Thanks in advance.

Upvotes: 0

Views: 828

Answers (2)

Omar Zaarour
Omar Zaarour

Reputation: 302

After some experimenting,

Your issue is in the X1,X2,Y1,Y2. You are not following math rules to find the exact values (it gets a bit hard to find them if you don't remember the triangle and circle equations like me :)).

My solution is to draw two straight lines, one from top to bottom and one from left to right then rotate them by 45 degrees.

The result will look like: enter image description here

The code is simple, I stretch the lines and rotate them so stick to the edges.

  <Grid Background="Black"  VerticalAlignment="Stretch"       HorizontalAlignment="Stretch" Width="15" Height="15">
    <Ellipse Height="15" Width="15" Fill="Red"/>
    <Line X1="7.5" Y1="0" X2="7.5" Y2="15" HorizontalAlignment="Center"  Stretch="Fill" VerticalAlignment="Center" Stroke="White" StrokeThickness="1"  StrokeStartLineCap="Round" StrokeEndLineCap="Round"  RenderTransformOrigin="0.5,0.5">
        <Line.RenderTransform>
            <RotateTransform Angle="45" />
        </Line.RenderTransform>
    </Line>
    <Line X1="0" Y1="7.5" X2="15" Y2="7.5" HorizontalAlignment="Center"  Stretch="Fill" VerticalAlignment="Center" Stroke="White" StrokeThickness="1"  StrokeStartLineCap="Round" StrokeEndLineCap="Round" RenderTransformOrigin="0.5,0.5">
        <Line.RenderTransform>
            <RotateTransform Angle="45" />
        </Line.RenderTransform>
    </Line>
</Grid>

Also notice that we set the origin of rotation in each line to be 0.5 and 0.5. This is a bit confusing ( why not 0,0) but this link will help you understand.

https://stackoverflow.com/a/5255115/2230348

Upvotes: 1

Clemens
Clemens

Reputation: 128070

No idea why exactly the line caps contribute to the line bounds on the right and bottom sides only, but as a workaround you could draw everything centered in a Canvas:

<Grid Background="Black">
    <Canvas HorizontalAlignment="Center" VerticalAlignment="Center">
        <Path Fill="Red">
            <Path.Data>
                <EllipseGeometry RadiusX="7.5" RadiusY="7.5"/>
            </Path.Data>
        </Path>
        <Path Data="M-5,-5 L5,5 M-5,5 L5,-5" StrokeThickness="1"
              Stroke="White" StrokeStartLineCap="Round" StrokeEndLineCap="Round"/>
    </Canvas>
</Grid>

Upvotes: 2

Related Questions