Omanshu Chaurasia
Omanshu Chaurasia

Reputation: 161

How do I create 2 rounded corners in winforms with borders?

I have a code that helped me make a rounded corner, border-less WinForm. It works fine but the thing is that it has no borders, so I want to add rounded borders to it. Also, I only want TopLeft and BottomRight corners to be rounded.

This is my current code:

public partial class mainForm : Form
{
    [DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
    private static extern IntPtr CreateRoundRectRgn
    (
        int nLeftRect,     // x-coordinate of upper-left corner
        int nTopRect,      // y-coordinate of upper-left corner
        int nRightRect,    // x-coordinate of lower-right corner
        int nBottomRect,   // y-coordinate of lower-right corner
        int nWidthEllipse, // height of ellipse
        int nHeightEllipse // width of ellipse
    );
}

public Form1()
{
    InitializeComponent();
    this.FormBorderStyle = FormBorderStyle.None;
    Region = System.Drawing.Region.FromHrgn(CreateRoundRectRgn(0, 0, Width, Height, 20, 20));
}

It is easily achievable in WPF but how do I get that in WinForms?

What should I do?

Upvotes: 1

Views: 1247

Answers (1)

Sinatr
Sinatr

Reputation: 22008

You can draw border manually in client area. It's very simple but you will have to take care to layout children controls with some margin.

And it is still a challenge though, because there is only Graphics.FillRegion and no way to draw outline or DrawRegion method.

We can create GraphicsPath and draw it with Graphics.DrawPath, but creating it is tricky, e.g. this implementation doesn't match to to created with CreateRoundRectRgn() method.

So there is a trick with 2 regions: bigger region with border color and smaller region inside with client color. This will leave little bit of outer region which will visually creates a border.

readonly Region _client;

public Form1()
{
    InitializeComponent();
    // calculate smaller inner region using same method
    _client = Region.FromHrgn(CreateRoundRectRgn(1, 1, Width - 1, Height - 1, 20, 20));
    Region = Region.FromHrgn(CreateRoundRectRgn(0, 0, Width, Height, 20, 20));
}

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    // FillRectangle is faster than FillRegion for drawing outer bigger region
    // and it's actually not needed, you can simply set form BackColor to wanted border color
    // e.Graphics.FillRectangle(Brushes.Red, ClientRectangle);
    e.Graphics.FillRegion(Brushes.White, _client);
}

Result:

Upvotes: 3

Related Questions