Hola, ahora crearemos un cuadro de imagen circular con un color degradado de borde, con varios tipos de estilo de línea, por ejemplo; solido, guiones, puntos, combinado entre guiones y punto, o simplemente sin borde. Tambien poder establecer el estilo de tapa al final o inicio de un guion, por ejemplo, un estilo plano, redondeado o triangular.
Hacerlo es muy sencillo, no tomará mucho tiempo 😉
1.- Crear clase
Primeramente agregar una nueva clase y colocar cualquier nombre, en mi caso pondré RJCircularPictureBox.
2.- Importar librería Windows.Form y Drawing
Para hacer cualquier control personalizado/extendido, es necesario importar la librería Windows Forms y la librería de dibujos (Drawing), opcionalmente, también importar la librería ComponentModel para implementar atributos en las propiedades del control.
using System.Windows.Forms; using System.Drawing; using System.Drawing.Drawing2D; using System.ComponentModel;
3.- Heredar la clase PictureBox
Heredar el control PictureBox, para así personalizar la apariencia y extender su funcionalidad.
class RJCircularPictureBox : PictureBox
{
}4.- Declarar campos
Una vez heredado la clase PictureBox, declarar campos para la apariencia y asignar sus valores predeterminados, en este caso: tamaño de borde, color de borde 1 y 2 para establecer un color degradado del borde, estilo de línea y tapa, finalmente un campo para el ángulo del degradado.
//Fields
private int borderSize = 2;
private Color borderColor = Color.RoyalBlue;
private Color borderColor2 = Color.HotPink;
private DashStyle borderLineStyle = DashStyle.Solid;
private DashCap borderCapStyle = DashCap.Flat;
private float gradientAngle = 50F;5.- Constructor
En el constructor, simplemente establecer un mismo tamaño para el alto y ancho. Y opcionalmente establecer el modo de tamaño, en este caso, indicaré que la imagen se ajuste al tamaño del cuadro de imagen.
//Constructor
public RJCircularPictureBox()
{
this.Size = new Size(100, 100);
this.SizeMode = PictureBoxSizeMode.StretchImage;
}6.- Generar propiedades
Crear los descriptores de acceso de los campos definidos anteriormente, y así poder cambiar la apariencia del control desde el cuadro de propiedades. Una vez creado las propiedades, en los descriptores de acceso Set, invocar el método Invalidate(), para repintar el control y así actualizar la apariencia.
//Properties
[Category("RJ Code Advance")]
public int BorderSize
{
get { return borderSize; }
set
{
borderSize = value;
this.Invalidate();
}
}
[Category("RJ Code Advance")]
public Color BorderColor
{
get { return borderColor; }
set
{
borderColor = value;
this.Invalidate();
}
}
[Category("RJ Code Advance")]
public Color BorderColor2
{
get { return borderColor2; }
set
{
borderColor2 = value;
this.Invalidate();
}
}
[Category("RJ Code Advance")]
public DashStyle BorderLineStyle
{
get { return borderLineStyle; }
set
{
borderLineStyle = value;
this.Invalidate();
}
}
[Category("RJ Code Advance")]
public DashCap BorderCapStyle
{
get { return borderCapStyle; }
set
{
borderCapStyle = value;
this.Invalidate();
}
}
[Category("RJ Code Advance")]
public float GradientAngle
{
get { return gradientAngle; }
set
{
gradientAngle = value;
this.Invalidate();
}
}7.- Anular el evento OnResize
Es necesario anular el método de evento OnResize, para que el cuadro de imagen circular tenga siempre el mismo alto y ancho, es decir, un círculo perfecto.
//Overridden methods
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
this.Size = new Size(this.Width, this.Width);
}8.- Anular el evento OnPaint
Finalmente, anular el método de evento OnPaint para agregar o crear una apariencia personalizada.
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
//Fields
var graph = pe.Graphics;
var rectContourSmooth = Rectangle.Inflate(this.ClientRectangle, -1, -1);
var rectBorder = Rectangle.Inflate(rectContourSmooth, -borderSize, -borderSize);
var smoothSize = borderSize > 0 ? borderSize * 3 : 1;
using (var borderGColor = new LinearGradientBrush(rectBorder, borderColor, borderColor2, gradientAngle))
using (var pathRegion = new GraphicsPath())
using (var penSmooth = new Pen(this.Parent.BackColor, smoothSize))
using (var penBorder = new Pen(borderGColor, borderSize))
{
graph.SmoothingMode = SmoothingMode.AntiAlias;
penBorder.DashStyle = borderLineStyle;
penBorder.DashCap = borderCapStyle;
pathRegion.AddEllipse(rectContourSmooth);
//Set rounded region
this.Region = new Region(pathRegion);
//Drawing
graph.DrawEllipse(penSmooth, rectContourSmooth);//Draw contour smoothing
if (borderSize > 0) //Draw border
graph.DrawEllipse(penBorder, rectBorder);
}
}