Reputation: 678
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:
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:
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
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 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
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