Controles comunes personalizados CSharp
La plataforma .NET desde su versión 1.1 ofrece la facilidad de poder generar controles comunes personalizados para satisfacer las necesidades de los desarrolladores que necesitan agregar, quitar o modificar el comportamiento, la funcionalidad y el diseño de cualquier control común (System.Windows.Forms.Control).
Clase Control
editarEn la clase Control (System.Windows.Forms.Control) se encuentran contenidos los siguientes controles comunes perzonalizables.
- AxHost
- ButtonBase
- DataGrid
- DataGridView
- DateTimePicker
- GroupBox
- Label
- ListControl
- ListView
- MdiClient
- MonthCalendar
- PictureBox
- PrintPreviewControl
- ProgressBar
- ScrollableControl
- ScrollBar
- Splitter
- StatusBar
- TabControl
- TextBoxBase
- ToolBar
- TrackBar
- TreeView
- WebBrowserBase
Ejemplo
editarSuponiendo que se necesita hacer una representación dinámica de un gráfico, para el cual es necesario que los vértices y aristas se comporten como botones para que se pueda hacer click sobre ellos; es necesario personalizar un botón (System.Windows.Forms.Button) de la siguiente manera:
Vértice
editarSe representa como un circulo con un identificador alfanumérico interno; plano, sin relleno (transparente), sin cambios al hacer click sobre el.
Definición de la clase
editarclass Vertice : Control
{
private string identificador;
public string Identificador { set { this.identificador = value; } get { return this.identificador; } }
public Vertice(string identificador)
{
//
}
}
Constructor
editarpublic Vertice(string identificador)
{
this.identificador = identificador;
//Propios del control
this.Enabled = true; //Habilita el control
base.CreateControl(); //Forza a crear el control
}
Eventos personalizados
editarprotected override void OnCreateControl()
{
using(var zona = new GraphicsPath())
{
zona.AddEllipse(new Rectangle(0, 0, 25, 25);
this.Region = new Region(zona); //La región del botón ahora es un círculo
}
base.OnCreateControl();
}
protected override void OnPaint(PaintEventArgs pevent)
{
Brush brushFuente;
Rectangle cajaVertice;
StringFormat formato;
pevent.Graphics.SmoothingMode = System.Drawing.SmoothingMode.AntiAlias;
pevent.Graphics.Clear();
formato = new StringFormat();
formato.Alignment = StringAlignment.Center;
formato.LineAlignment = StringAlignment.Center;
brushFuente = new System.Drawing.SolidBrush(System.Drawing.Color.Black);
cajaVertice = new System.Drawing.Rectangle(0, 0, 25, 25);
pevent.Graphics.DrawEllipse(new System.Drawing.Pen(System.Drawing.Color.Black),
3, cajaVertice);
pevent.Graphics.DrawString(this.Identificador,
new System.Drawing.Font("Arial", 12),
brushFuente, cajaVertice, formato);
}
Arista
editarSe representa como una linea recta que une a 2 vértices en cualquier parte del área cliente; con relleno, sin cambios al hacer click sobre ella.
Definición de la clase
editarclass Arista : Control
{
private Vertice origen;
private Vertice destino;
private Arista siguiente;
public Vertice Origen { set { this.origen = value; } get { return this.origen; } }
public Vertice Destino { set { this.destino = value; } get { return this.destino; } }
public Arista Siguiente { set { this.siguiente = value; } get { return this.siguiente;} }
public Arista(Vertice origen, Vertice destino)
{
//
}
}
Constructor
editarpublic Arista(Vertice origen, Vertice destino)
{
this.origen = origen;
this.destino = destino;
this.siguiente = null;
//Propios del control
this.Enabled = true;
base.CreateControl();
}
Eventos personalizados
editarHay que tener en cuenta que por definición en el método System.Drawing.Drawing2D.GraphicsPath.AddLine agrega una linea con grosor cero (sin volumen), ya que normalmente se espera que la región se forme a partir de una figura cerrada, por lo que es necesario especificar un ancho para que esta linea tome un grosor mayor a cero y con esto el nuevo botón sea visible en el área cliente al momento de dibujarlo.
protected override void OnCreateControl()
{
using(var zona = new GraphicsPath())
{
zona.AddLine(this.origen.Location.X + 20,
this.origen.Location.Y + 20,
this.destino.Location.X + 20,
this.destino.Location.Y + 20);
zona.Widen(new Pen(System.Drawing.Color.Black, 2)); //Default = Black, 0
this.Region = new Region(zona); //La región del botón ahora es una linea
} //con grosor de 2 unidades
base.OnCreateControl();
}
protected override void OnPaint(PaintEventArgs pevent)
{
superficie.SmoothingMode = SmoothingMode.AntiAlias;
superficie.DrawLine(new Pen(System.Drawing.Color.Black, 2),
this.origen.Location.X + 20,
this.origen.Location.Y + 20,
this.destino.Location.X + 20,
this.destino.Location.Y + 20);
}