So... I have made an override to my OnPaint event to get rounded corners, and it sorta worked, but it had a huge problem: no antialiasing due to doing it with a Region.
So I dropped that and switched to e.Graphics.DrawPath, which, again, sorta works. It gives me the shape I want and smooth edges. Just one problem... There seems to be a black rectangle behind it (as per the image below)
My code is as follows (and no, I didn't forget base.OnPaint(e), I tried putting that in many spots on this code and it just made things worse):
public class Button : System.Windows.Forms.Button
{
public BorderRadius BorderRadius { get; set; } = new BorderRadius(0);
public Color BorderColor { get; set; } = Color.Transparent;
protected override void OnPaint(PaintEventArgs e) {
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
SolidBrush brush = new(BackColor);
GraphicsPath gp = Transform.BorderRadius(ClientRectangle, new(40));
gp.CloseFigure();
StringFormat formatter = new() {
LineAlignment = StringAlignment.Center,
Alignment = StringAlignment.Center
};
RectangleF rectangle = new(0, 0, e.ClipRectangle.Width, e.ClipRectangle.Height);
e.Graphics.FillRectangle(new SolidBrush(Color.Transparent), ClientRectangle);
e.Graphics.FillPath(brush, gp);
e.Graphics.DrawString(Text, Font, new SolidBrush(ForeColor), rectangle, formatter);
}
}
If you are interested in the Transform and BorderRadius classes they are in the snippet below, but I don't think they are the problem:
class Transform
{
public static GraphicsPath BorderRadius(Rectangle pRect, BorderRadius borderRadius) {
GraphicsPath gp = new GraphicsPath();
if (borderRadius.TopLeft > 0) {
gp.AddArc(
pRect.X,
pRect.Y,
borderRadius.TopLeft,
borderRadius.TopLeft,
180,
90
);
} else {
gp.AddLine(
pRect.X,
pRect.Y,
pRect.X + pRect.Width - borderRadius.TopRight,
pRect.Y
);
}
if (borderRadius.TopRight > 0) {
gp.AddArc(
pRect.X + pRect.Width - borderRadius.TopRight,
pRect.Y,
borderRadius.TopRight,
borderRadius.TopRight,
270,
90
);
} else {
gp.AddLine(
pRect.X + borderRadius.TopLeft,
pRect.Y,
pRect.X + pRect.Width,
pRect.Y
);
}
if (borderRadius.BottomRight > 0) {
gp.AddArc(
pRect.X + pRect.Width - borderRadius.BottomRight,
pRect.Y + pRect.Height - borderRadius.BottomRight,
borderRadius.BottomRight,
borderRadius.BottomRight,
0,
90
);
} else {
gp.AddLine(
pRect.X + pRect.Width,
pRect.Y + pRect.Height,
pRect.X + borderRadius.BottomLeft,
pRect.Y + pRect.Height
);
}
if (borderRadius.BottomLeft > 0) {
gp.AddArc(
pRect.X,
pRect.Y + pRect.Height - borderRadius.BottomLeft,
borderRadius.BottomLeft,
borderRadius.BottomLeft,
90,
90
);
} else {
gp.AddLine(
pRect.X + pRect.Width - borderRadius.BottomRight,
pRect.Y + pRect.Height,
pRect.X,
pRect.Y + pRect.Height
);
}
return gp;
}
}
public class BorderRadius {
public int TopLeft { get; init; } = 0;
public int TopRight { get; init; } = 0;
public int BottomLeft { get; init; } = 0;
public int BottomRight { get; init; } = 0;
public BorderRadius(int all) {
TopLeft = TopRight = BottomLeft = BottomRight = all;
}
public BorderRadius(int topLeftAndBottomRight, int topRightAndBottomLeft) {
TopLeft = BottomRight = topLeftAndBottomRight;
TopRight = BottomLeft = topRightAndBottomLeft;
}
public BorderRadius(int topLeft, int topRightAndBottomLeft, int bottomRight) {
TopRight = BottomLeft = topRightAndBottomLeft;
TopLeft = topLeft;
BottomRight = bottomRight;
}
public BorderRadius(int topLeft, int topRight, int bottomRight, int bottomLeft) {
TopLeft = topLeft;
TopRight = topRight;
BottomLeft = bottomLeft;
BottomRight = bottomRight;
}
public void Deconstruct(out int topLeft, out int topRight, out int bottomRight, out int bottomLeft) {
topLeft = TopLeft;
topRight = TopRight;
bottomRight = BottomRight;
bottomLeft = BottomLeft;
}
}