So i have this roundedPanel Component working very good. The corners are smooth as they should be, but that lasts till i set an image as background:
above looks as it should but if i add an image to it this is how it looks:
i only changed the background color so it will be more visible. Here's the close up:
So this is the first issue. And the second issue is the fact that if i add another image behind it, it isn't transparent. I tryied to add the folowing code to it so i will make it transparent but it completely removes the smoothness:
public void ApplyRoundedCorners(Panel panel, int cornerRadius)
{
panel.Paint += (sender, e) =>
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
int diameter = cornerRadius * 2;
GraphicsPath path = new GraphicsPath();
// Define the rounded rectangle
path.StartFigure();
path.AddArc(new Rectangle(0, 0, diameter, diameter), 180, 90);
path.AddArc(new Rectangle(panel.Width - diameter - 1, 0, diameter, diameter), 270, 90);
path.AddArc(new Rectangle(panel.Width - diameter - 1, panel.Height - diameter - 1, diameter, diameter), 0, 90);
path.AddArc(new Rectangle(0, panel.Height - diameter - 1, diameter, diameter), 90, 90);
path.CloseFigure();
// Set the clip region
panel.Region = new Region(path);
// Draw the border
using (Pen pen = new Pen(Color.Black, 1)) // Change the color and width as needed
{
e.Graphics.DrawPath(pen, path);
}
path.Dispose();
};
panel.Invalidate(); // Force the panel to repaint
}
This is my whole class code:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
public class RoundedPanel : Panel
{
private Color gradientStartColor = Color.DarkSlateBlue;
private Color gradientEndColor = Color.MediumPurple;
private int cornerRadius = 35;
private Image backgroundImage;
public RoundedPanel()
{
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);
}
[Browsable(true)]
[Category("Appearance")]
[Description("The start color of the gradient.")]
public Color GradientStartColor
{
get => gradientStartColor;
set
{
gradientStartColor = value;
this.Invalidate();
}
}
[Browsable(true)]
[Category("Appearance")]
[Description("The end color of the gradient.")]
public Color GradientEndColor
{
get => gradientEndColor;
set
{
gradientEndColor = value;
this.Invalidate();
}
}
[Browsable(true)]
[Category("Appearance")]
[Description("The radius of the rounded corners.")]
public int CornerRadius
{
get => cornerRadius;
set
{
cornerRadius = value;
this.Invalidate();
}
}
[Browsable(true)]
[Category("Appearance")]
[Description("The background image of the panel.")]
public new Image BackgroundImage
{
get => backgroundImage;
set
{
backgroundImage = value;
this.Invalidate();
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics graphics = e.Graphics;
Rectangle gradientRectangle = new Rectangle(0, 0, this.Width - 1, this.Height - 1);
if (backgroundImage != null)
{
// Draw the background image
if (ImageAnimator.CanAnimate(backgroundImage))
{
ImageAnimator.UpdateFrames(backgroundImage);
}
graphics.SmoothingMode = SmoothingMode.HighQuality;
using (GraphicsPath path = RoundedRectangle.RoundedRect(gradientRectangle, CornerRadius))
{
Region region = new Region(path);
graphics.SetClip(region, CombineMode.Replace);
graphics.DrawImage(backgroundImage, gradientRectangle);
graphics.ResetClip();
}
}
else
{
// Draw the gradient background
using (Brush b = new LinearGradientBrush(gradientRectangle, GradientStartColor, GradientEndColor, 0.0f))
{
graphics.SmoothingMode = SmoothingMode.HighQuality;
RoundedRectangle.FillRoundedRectangle(graphics, b, gradientRectangle, CornerRadius);
}
}
foreach (Control ctrl in this.Controls)
{
using (Bitmap bmp = new Bitmap(ctrl.Width, ctrl.Height))
{
Rectangle rect = new Rectangle(0, 0, ctrl.Width, ctrl.Height);
ctrl.DrawToBitmap(bmp, rect);
graphics.DrawImage(bmp, ctrl.Location);
}
}
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
return cp;
}
}
}
public static class RoundedRectangle
{
public static GraphicsPath RoundedRect(Rectangle bounds, int radius)
{
int diameter = radius * 2;
Size size = new Size(diameter, diameter);
Rectangle arc = new Rectangle(bounds.Location, size);
GraphicsPath path = new GraphicsPath();
if (radius == 0)
{
path.AddRectangle(bounds);
return path;
}
// top left arc
path.AddArc(arc, 180, 90);
// top right arc
arc.X = bounds.Right - diameter;
path.AddArc(arc, 270, 90);
// bottom right arc
arc.Y = bounds.Bottom - diameter;
path.AddArc(arc, 0, 90);
// bottom left arc
arc.X = bounds.Left;
path.AddArc(arc, 90, 90);
path.CloseFigure();
return path;
}
public static void FillRoundedRectangle(Graphics graphics, Brush brush, Rectangle bounds, int cornerRadius)
{
if (graphics == null)
throw new ArgumentNullException(nameof(graphics));
if (brush == null)
throw new ArgumentNullException(nameof(brush));
using (GraphicsPath path = RoundedRect(bounds, cornerRadius))
{
graphics.FillPath(brush, path);
}
}
}
I would appreciate help. Thanks!
As mentioned above i tryied adding that additional code. It works but not well, as it does exactly what i dont want it to do, making the corners pixelated.
Parent.BackColor
+SmoothingMode.AntiAlias
to draw the path. See also stackoverflow.com/a/54794097/14171304