Home > Software engineering >  Why is the Border CornerRadius not maintained for different BorderThickness?
Why is the Border CornerRadius not maintained for different BorderThickness?

Time:09-17

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" />

enter image description here

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" />

enter image description here

EDIT #2:

So that it's even more obvious how big the corner radius of the bottom Border is compared to the top one:

enter image description here

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.

enter image description here

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..

enter image description here

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>

enter image description here

  • Related