I want to have a rounded custom button, for this aim I created a class extended from Button class:
public class CustomButton : Button
{
//Fields
private int borderSize = 0;
private int borderRadius = 40;
private Color borderColor = Color.PaleVioletRed;
[Category("Custom Controls")]
public int BorderSize
{
get
{
return borderSize;
}
set
{
borderSize = value;
this.Invalidate();
}
}
[Category("Custom Controls")]
public int BorderRadius
{
get
{
return borderRadius;
}
set
{
borderRadius = value;
this.Invalidate();
}
}
[Category("Custom Controls")]
public Color BorderColor {
get
{
return borderColor;
}
set
{
borderColor = value;
this.Invalidate();
}
}
[Category("Custom Controls")]
public Color TextColor
{
get
{
return this.ForeColor;
}
set
{
this.ForeColor = value;
}
}
//Constructor
CustomButton()
{
this.FlatStyle = FlatStyle.Flat;
this.FlatAppearance.BorderSize = 0;
this.Size = new Size(150,40);
this.BackColor = Color.MediumSlateBlue;
this.ForeColor = Color.White;
}
//Methods
private GraphicsPath GetFigurePath(RectangleF rect,float radius)
{
GraphicsPath path = new GraphicsPath();
path.StartFigure();
path.AddArc(rect.X, rect.Y, radius, radius, 180, 90);
path.AddArc(rect.Width - radius, rect.Y, radius, radius, 270, 90);
path.AddArc(rect.Width - radius, rect.Height - radius, radius, radius, 0, 90);
path.AddArc(rect.X, rect.Height-radius, radius, radius, 90, 90);
path.CloseFigure();
return path;
}
protected override void OnPaint(PaintEventArgs pevent)
{
base.OnPaint(pevent);
pevent.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
RectangleF rectSurface = new RectangleF(0, 0, this.Width, this.Height);
RectangleF rectBorder = new RectangleF(1, 1, this.Width - 0.8F, this.Height - 1);
if(borderRadius > 2) //Rounded Button
{
using (GraphicsPath pathSurface = GetFigurePath(rectSurface, borderRadius))
using (GraphicsPath pathBorder = GetFigurePath(rectBorder, borderRadius-1F))
using (Pen penSurface = new Pen(this.Parent.BackColor, 2))
using (Pen penBorder = new Pen(borderColor, borderSize))
{
penBorder.Alignment = PenAlignment.Inset;
//button Surface
this.Region = new Region(pathSurface);
//Draw Surface Border for HD result
pevent.Graphics.DrawPath(penBorder, pathBorder);
//Button border
if (borderSize >= 1)
//Draw Control border
pevent.Graphics.DrawPath(penBorder, pathBorder);
}
}
else //Normal Button
{
//Button surface
this.Region = new Region(rectSurface);
//Button border
if(borderSize >= 1)
{
using (Pen penBorder = new Pen(borderColor, borderSize))
{
penBorder.Alignment = PenAlignment.Inset;
pevent.Graphics.DrawRectangle(penBorder, 0, 0, this.Width - 1, this.Height - 1);
}
}
}
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);base.OnHandleCreated(e);
this.Parent.BackColorChanged = new EventHandler(Container_BackColorChanged);
}
private void Container_BackColorChanged(object sender, EventArgs e)
{
if (this.DesignMode)
this.Invalidate();
}
private void InitializeComponent()
{
this.SuspendLayout();
this.ResumeLayout(false);
}
}
}
But when I use my custom button, I get this warning:
Field 'frmMainPanel.customButton1' is never assigned to, and will always have its default value null
And when running app, get: in this error I get 'Object reference not set to an instance of an object.' but can't resolve this problem
CodePudding user response:
The default constructor CustomButton is private. Change it to public. public CustomButton()