Cómo: Desarrollar un control de formularios Windows Forms sencillo
Actualización: noviembre 2007
En esta sección se ofrece un tutorial que describe los pasos básicos para crear un control de formularios Windows Forms personalizado. El control sencillo desarrollado en este tutorial permite modificar la alineación de su propiedad Text. No provoca ni controla eventos.
Para crear un control personalizado sencillo
Defina una clase que se derive de System.Windows.Forms.Control.
Public Class FirstControl Inherits Control End Class
public class FirstControl:Control{}
Defina propiedades. (No es necesario definir propiedades, ya que los controles heredan muchas propiedades de la clase Control, aunque para la mayoría de los controles personalizados se suelen definir propiedades adicionales.) En el fragmento de código siguiente se define una propiedad denominada TextAlignment que FirstControl utiliza para dar formato a la apariencia de la propiedad Text heredada de Control. Para obtener más información sobre la definición de propiedades, vea Información general sobre propiedades.
' ContentAlignment is an enumeration defined in the System.Drawing ' namespace that specifies the alignment of content on a drawing ' surface. Private alignmentValue As ContentAlignment = ContentAlignment.MiddleLeft <Category("Alignment"), Description("Specifies the alignment of text.")> _ Public Property TextAlignment() As ContentAlignment Get Return alignmentValue End Get Set alignmentValue = value ' The Invalidate method invokes the OnPaint method described ' in step 3. Invalidate() End Set End Property
// ContentAlignment is an enumeration defined in the System.Drawing // namespace that specifies the alignment of content on a drawing // surface. private ContentAlignment alignmentValue = ContentAlignment.MiddleLeft;
Cuando se establece una propiedad que cambia la apariencia visual del control, se debe invocar el método Invalidate para volver a dibujar el control. Invalidate se define en la clase base Control.
Reemplace el método protegido OnPaint heredado de Control para proporcionar lógica de representación al control. Si no reemplaza OnPaint, el control no podrá dibujarse a sí mismo. En el fragmento de código siguiente, el método OnPaint muestra la propiedad Text heredada de Control con la alineación especificada por el campo alignmentValue.
Protected Overrides Sub OnPaint(e As PaintEventArgs) MyBase.OnPaint(e) Dim style As New StringFormat() style.Alignment = StringAlignment.Near Select Case alignmentValue Case ContentAlignment.MiddleLeft style.Alignment = StringAlignment.Near Case ContentAlignment.MiddleRight style.Alignment = StringAlignment.Far Case ContentAlignment.MiddleCenter style.Alignment = StringAlignment.Center End Select ' Call the DrawString method of the System.Drawing class to write ' text. Text and ClientRectangle are properties inherited from ' Control. e.Graphics.DrawString( _ me.Text, _ me.Font, _ New SolidBrush(ForeColor), _ RectangleF.op_Implicit(ClientRectangle), _ style) End Sub
protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); StringFormat style = new StringFormat(); style.Alignment = StringAlignment.Near; switch (alignmentValue) { case ContentAlignment.MiddleLeft: style.Alignment = StringAlignment.Near; break; case ContentAlignment.MiddleRight: style.Alignment = StringAlignment.Far; break; case ContentAlignment.MiddleCenter: style.Alignment = StringAlignment.Center; break; } // Call the DrawString method of the System.Drawing class to write // text. Text and ClientRectangle are properties inherited from // Control. e.Graphics.DrawString( Text, Font, new SolidBrush(ForeColor), ClientRectangle, style); }
Proporcione atributos para el control. Los atributos permite a los diseñadores visuales mostrar el control y sus propiedades y evento correctamente en tiempo de diseño. El fragmento de código siguiente aplica atributos a la propiedad TextAlignment. En un diseñador como Visual Studio, el atributo Category (que aparece en el fragmento de código) hace que se muestre la propiedad en una categoría lógica. El atributo Description hace que se muestre una cadena descriptiva en la parte inferior de la ventana Propiedades cuando se selecciona la propiedad TextAlignment. Para obtener más información sobre controles, vea Atributos en tiempo de diseño para componentes.
<Category("Alignment"), Description("Specifies the alignment of text.")> _ Public Property TextAlignment() As ContentAlignment
[ Category("Alignment"), Description("Specifies the alignment of text.") ]
(opcional) Proporcione recursos para el control. Para proporcionar un recurso, como un mapa de bits, al control, utilice una opción del compilador (/res para C#) para empaquetar recursos con el control. En tiempo de ejecución, el recurso se puede recuperar utilizando los métodos de la clase ResourceManager. Para obtener más información sobre cómo crear y utilizar los recursos, vea Recursos en aplicaciones.
Compile e implemente el control. Para compilar e implementar FirstControl, realice los pasos siguientes.
Guarde el código del siguiente ejemplo en un archivo de código fuente (como FirstControl.cs o FirstControl.vb).
Compile el código fuente en un ensamblado y guárdelo en el directorio de la aplicación. Para ello, ejecute el siguiente comando desde el directorio que contiene el archivo de código fuente.
vbc /t:library /out:[path to your application's directory]/CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll FirstControl.vb
csc /t:library /out:[path to your application's directory]/CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll FirstControl.cs
La opción del compilador /t:library indica al compilador que el ensamblado que se está creando es una biblioteca (y no un ejecutable). La opción /out especifica la ruta de acceso y el nombre del ensamblado. La opción /r indica el nombre de los ensamblados a los que hace referencia el código. En este ejemplo, se crea un ensamblado privado que sólo pueden utilizar sus aplicaciones. Por tanto, debe guardarlo en el directorio de su aplicación. Para obtener más información sobre cómo empaquetar e implementar un control para la distribución, vea Implementar aplicaciones de .NET Framework.
En el siguiente ejemplo se muestra el código de FirstControl. El control está incluido en el espacio de nombres CustomWinControls. Un espacio de nombres proporciona una agrupación lógica de tipos relacionados. El control se puede crear en un espacio de nombres nuevo o en uno existente. En C#, la declaración using (en Visual Basic, Imports) permite el acceso a los tipos desde un espacio de nombres sin utilizar el nombre completo del tipo. En el ejemplo siguiente, la declaración using permite al código tener acceso a la clase Control desde System.Windows.Forms simplemente como Control en lugar de tener que usar el nombre completo de System.Windows.Forms.Control.
Imports System
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms
Public Class FirstControl
Inherits Control
Public Sub New()
End Sub
' ContentAlignment is an enumeration defined in the System.Drawing
' namespace that specifies the alignment of content on a drawing
' surface.
Private alignmentValue As ContentAlignment = ContentAlignment.MiddleLeft
<Category("Alignment"), Description("Specifies the alignment of text.")> _
Public Property TextAlignment() As ContentAlignment
Get
Return alignmentValue
End Get
Set
alignmentValue = value
' The Invalidate method invokes the OnPaint method described
' in step 3.
Invalidate()
End Set
End Property
Protected Overrides Sub OnPaint(e As PaintEventArgs)
MyBase.OnPaint(e)
Dim style As New StringFormat()
style.Alignment = StringAlignment.Near
Select Case alignmentValue
Case ContentAlignment.MiddleLeft
style.Alignment = StringAlignment.Near
Case ContentAlignment.MiddleRight
style.Alignment = StringAlignment.Far
Case ContentAlignment.MiddleCenter
style.Alignment = StringAlignment.Center
End Select
' Call the DrawString method of the System.Drawing class to write
' text. Text and ClientRectangle are properties inherited from
' Control.
e.Graphics.DrawString( _
me.Text, _
me.Font, _
New SolidBrush(ForeColor), _
RectangleF.op_Implicit(ClientRectangle), _
style)
End Sub
End Class
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace CustomWinControls
{
public class FirstControl : Control
{
public FirstControl()
{
}
// ContentAlignment is an enumeration defined in the System.Drawing
// namespace that specifies the alignment of content on a drawing
// surface.
private ContentAlignment alignmentValue = ContentAlignment.MiddleLeft;
[
Category("Alignment"),
Description("Specifies the alignment of text.")
]
public ContentAlignment TextAlignment
{
get
{
return alignmentValue;
}
set
{
alignmentValue = value;
// The Invalidate method invokes the OnPaint method described
// in step 3.
Invalidate();
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
StringFormat style = new StringFormat();
style.Alignment = StringAlignment.Near;
switch (alignmentValue)
{
case ContentAlignment.MiddleLeft:
style.Alignment = StringAlignment.Near;
break;
case ContentAlignment.MiddleRight:
style.Alignment = StringAlignment.Far;
break;
case ContentAlignment.MiddleCenter:
style.Alignment = StringAlignment.Center;
break;
}
// Call the DrawString method of the System.Drawing class to write
// text. Text and ClientRectangle are properties inherited from
// Control.
e.Graphics.DrawString(
Text,
Font,
new SolidBrush(ForeColor),
ClientRectangle, style);
}
}
}
Utilizar el control personalizado en un formulario
En el siguiente ejemplo se muestra un formulario sencillo que utiliza FirstControl. Crea tres instancias de FirstControl, cada una con un valor distinto de la propiedad TextAlignment.
Para compilar y ejecutar este ejemplo
Guarde el código del siguiente ejemplo en un archivo de código fuente (SimpleForm.cs o SimpleForms.vb).
Compile el código fuente en un ensamblado ejecutable; para ello, ejecute el siguiente comando desde el directorio que contiene el archivo de código fuente.
vbc /r:CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll SimpleForm.vb
csc /r:CustomWinControls.dll /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll SimpleForm.cs
CustomWinControls.dll es el ensamblado que contiene la clase FirstControl. Este ensamblado debe encontrarse en el mismo directorio que el archivo de código fuente del formulario que tiene acceso a él. (SimpleForm.cs o SimpleForms.vb).
Ejecute SimpleForm.exe con el siguiente comando.
SimpleForm
Imports System
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms
Public Class SimpleForm
Inherits System.Windows.Forms.Form
Private firstControl1 As FirstControl
Private components As System.ComponentModel.Container = Nothing
Public Sub New()
InitializeComponent()
End Sub
Private Sub InitializeComponent()
Me.firstControl1 = New FirstControl()
Me.SuspendLayout()
'
' firstControl1
'
Me.firstControl1.BackColor = System.Drawing.SystemColors.ControlDark
Me.firstControl1.Location = New System.Drawing.Point(96, 104)
Me.firstControl1.Name = "firstControl1"
Me.firstControl1.Size = New System.Drawing.Size(75, 16)
Me.firstControl1.TabIndex = 0
Me.firstControl1.Text = "Hello World"
Me.firstControl1.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter
'
' SimpleForm
'
Me.ClientSize = New System.Drawing.Size(292, 266)
Me.Controls.Add(firstControl1)
Me.Name = "SimpleForm"
Me.Text = "SimpleForm"
Me.ResumeLayout(False)
End Sub
<STAThread()> _
Shared Sub Main()
Application.Run(New SimpleForm())
End Sub
End Class
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace CustomWinControls
{
public class SimpleForm : System.Windows.Forms.Form
{
private FirstControl firstControl1;
private System.ComponentModel.Container components = null;
public SimpleForm()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
private void InitializeComponent()
{
this.firstControl1 = new FirstControl();
this.SuspendLayout();
//
// firstControl1
//
this.firstControl1.BackColor = System.Drawing.SystemColors.ControlDark;
this.firstControl1.Location = new System.Drawing.Point(96, 104);
this.firstControl1.Name = "firstControl1";
this.firstControl1.Size = new System.Drawing.Size(75, 16);
this.firstControl1.TabIndex = 0;
this.firstControl1.Text = "Hello World";
this.firstControl1.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter;
//
// SimpleForm
//
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.firstControl1);
this.Name = "SimpleForm";
this.Text = "SimpleForm";
this.ResumeLayout(false);
}
[STAThread]
static void Main()
{
Application.Run(new SimpleForm());
}
}
}
Vea también
Conceptos
Eventos de los controles de formularios Windows Forms