Why does the BorderThickness
changes the rendered CornerRadius
?
Also, what is the design reasoning/philosophy behind it? I just cannot understand it, maybe I'm missing something.
<Border Width="300"
Height="300"
Background="Red"
BorderBrush="Blue"
CornerRadius="5"
BorderThickness="50" />
<Border Width="300"
Height="300"
Background="Red"
BorderBrush="Blue"
CornerRadius="5"
BorderThickness="10" />
I see Rectangle has the same behavior.
Is there any element in WPF or WinUI which I can use to draw an exact radius so I can respect the designer's requirement?
Besides Path with custom points, I do not see any other way. The issue with Path is I need to recompute the points myself when width/height changes which will hurt performance.
EDIT: Trying to tweak the corner radius so that it can match the design spec turns out to be impossible.
For example, let's assume the designer wants a Border with CornerRadius=5 and BorderThickness = 30.
In the image below, the top Border shows what an actual CornerRadius=5 looks like.
In the bottom Border, I try to meet the design spec. I set the BorderThicikness=30 and I tweak the CornerRadius to something very small so that it looks close to the corner radius of the Border above.
But the CornerRadius remains quite big even for a very small value 0.0000002
:
<Border Width="100"
Height="100"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="Red"
BorderThickness="0"
CornerRadius="5"/>
<Border Width="100"
Height="100"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="Red"
BorderBrush="Blue"
BorderThickness="30"
CornerRadius="0.0000002" />
EDIT #2:
So that it's even more obvious how big the corner radius of the bottom Border is compared to the top one:
CodePudding user response:
Why does the BorderThickness changes the rendered CornerRadius?
Looking at Border's method OnRender
, there is a Pen
which aim at drawing a rounded rectangle if CornerRadius
property is set... the pen has Thickness
Property, Pen's thickness = Border's thickness.
This is the flow of execution inside OnRender
method when both CornerRadius
and BorderThickness
are set (in case of uniform thickness and uniform radius)..
pen1 = new Pen();
pen1.Brush = borderBrush;
pen1.Thickness = borderThickness.Left;
double topLeft1 = cornerRadius.TopLeft;
double num = pen1.Thickness * 0.5;
Rect rectangle = new Rect(new Point(num, num), new Point(this.RenderSize.Width - num, this.RenderSize.Height - num));
dc.DrawRoundedRectangle((Brush) null, pen1, rectangle, topLeft1, topLeft1);
So there is a Thickness-Radius trade-off that can not be avoided, And probably the only way to deal with it is to set a base border (the border that meets the designer's guidelines) and for the other border you would increase its radius if its thickness is less than the base border's thickness!
Update
Note that the dimensions of the border (Width
and Height
) is the third factor in the equation (see DrawRoundedRectangle
call).
Imagine you are about to draw a rectangle of size 100x100 using a pen with thickness = 30.. You start drawing from the middle of the top line and moving the pen towards the left (image below).. Now, you will start shifting the pen early before reaching the corner because you are not allowed to get out of the 100x100, and that will result in a big curve so the value of the radius will not take affect in this case because the Width
and Height
has higher priority that the CornerRadius
.
So to let a very small radius like 0.0000002
take affect, you have to enlarge the dimensions of the rectangle to a size that a pen with thickness = 30 will look small enough to reache near the corners.
Here is the first xaml code after tweaking radius of the second border (set it to 20) to make it looks like the first border..
And to make the first border looks like the second border, you can change its code to this
<Grid>
<Border
Width="300"
Height="300"
BorderBrush="Blue"
BorderThickness="10"
CornerRadius="5" />
<Border
Width="300"
Height="300"
Background="Red"
BorderBrush="Blue"
BorderThickness="50"
CornerRadius="5" />
</Grid>