简体   繁体   中英

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?

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, eg 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:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM