How to create a User Control with rounded corners?

前端 未结 3 1985
不思量自难忘°
不思量自难忘° 2020-12-06 12:09

I am trying to have a User Control that has rounded corners. It doesnt have a fixed size but it usually doesnt have a width much more than 120 pixels.

I need the Use

相关标签:
3条回答
  • 2020-12-06 12:40

    I have answered my own question.

    Following Sinatr's comment i have found i was unable to use the OnHandleCreated as i needed to be about to paint the object before i knew what its size would be. Following the link Sinatr provided GetRoundedRegion exception

    So what i have done is added a IntPtr variable to my UserControl which is asigned on the CreateRoundRectRgn method every paint with the handle. Before this triggers i am using the DeleteObject to remove the old handle.

    Not an optimal solution but appears to be working fine for now.

    The other suggestions whilst good, wouldnt work in my case.

    0 讨论(0)
  • 2020-12-06 12:51

    Setting the Region makes sense only if you want to "click through" the transparent area. If the rounded corners are not so large and you want just to make the corners visually transparent, you can do the same as Button does.

    The advantage of this solution that you can have a nice anti-aliased rounded corner here, while the edges of a region are always sharp. Not mentioning that a Region instance is holding unmanaged resources and should be disposed somehow.

    protected override void OnPaint(PaintEventArgs e)
    {
        PaintTransparentBackground(this, e);
        // TODO: Paint your actual content here with rounded corners
    }
    
    private static void PaintTransparentBackground(Control c, PaintEventArgs e)
    {
        if (c.Parent == null || !Application.RenderWithVisualStyles)
            return;
    
        ButtonRenderer.DrawParentBackground(e.Graphics, c.ClientRectangle, c);
    }
    
    0 讨论(0)
  • 2020-12-06 12:56

    If you want really round corner and not only transparent trick you can use this example:

    private int radius=20;
    [DefaultValue(20)]
    public int Radius
    {
        get { return radius; }
        set
        {
            radius = value;
            this.RecreateRegion();
        }
    }
    private GraphicsPath GetRoundRectagle(Rectangle bounds, int radius)
    {
        GraphicsPath path = new GraphicsPath();
        path.AddArc(bounds.X, bounds.Y, radius, radius, 180, 90);
        path.AddArc(bounds.X + bounds.Width - radius, bounds.Y, radius, radius, 270, 90);
        path.AddArc(bounds.X + bounds.Width - radius, bounds.Y + bounds.Height - radius, 
                    radius, radius, 0, 90);
        path.AddArc(bounds.X, bounds.Y + bounds.Height - radius, radius, radius, 90, 90);
        path.CloseAllFigures();
        return path;
    }
    private void RecreateRegion()
    {
        var bounds = ClientRectangle;
        bounds.Width--; bounds.Height--;
        using (var path = GetRoundRectagle(bounds, this.Radius))
            this.Region = new Region(path);
        this.Invalidate();
    }
    protected override void OnSizeChanged(EventArgs e)
    {
        base.OnSizeChanged(e);
        this.RecreateRegion();
    }
    

    And screenshot will be:

    The difference between this approach and making transparent:

    • Setting round region, the control has really round corners and you can see what is behind the round part despite when it is transparent, you will see background of form.
    • Setting round region, when you click on removed rounded part, click pass through the region and reaches behind, but if you use transparency trick click on transparent region will handle by the control.

    You can use any of these 2 options. Making transparent or setting region based on your requirement.

    Download

    You can download the code or clone the repository here:

    • r-aghaei/RoundCornerControlExample
    0 讨论(0)
提交回复
热议问题