You are on page 1of 15

Creacin de controles de Visual Basic .

NET desde cero


Nunca he sentido la tentacin de convertirme en programador de C++, ya que soy demasiado perezoso
para trabajar tanto. Sin embargo, debo admitir que envidiaba a los programadores de C++ su capacidad
para escribir controles visuales.
Los controles en Visual Basic 6.0 y versiones anteriores se limitaban a controles compuestos (controles
formados por otros) denominados UserControls. Escribir un control que tuviera su propia representacin
visual en la pantalla en Visual Basic 6.0 era una tarea entre difcil e imposible.
La buena noticia es que ahora Visual Basic .NET permite escribir todo tipo de controles visuales. An
dispone de UserControls compuestos y tambin puede heredar de un control existente, como TextBox, y
ampliarlo con nuevas capacidades. Es ms, puede escribir un control visual desde cero que presente su
propia interfaz.
En este artculo, har una demostracin de esta capacidad mediante la creacin de un control visual
completo desde cero. El control es un semforo, es decir, un rectngulo con crculos en rojo, amarillo y
verde. En la figura 1 se muestra la apariencia del control con cada una de las luces encendidas y con el
color de fondo del control establecido en el color del sistema ControlDark.

Figura 1. Formulario con tres controles TrafficLight, cada uno con una luz diferente
encendida.
Lo llamaremos control TrafficLight y podr cambiar la luz activa, mediante cdigo o mediante clics por
parte del usuario.
Puesto que TrafficLight es un control de Windows Forms visual, heredar de la clase Control en el
espacio de nombres System.Windows.Forms. Esto nos proporcionar gran cantidad de propiedades,
mtodos y eventos predefinidos. Entre ellos, se incluyen propiedades para el control de la apariencia,
como ForeColor, BackColor, Size yLocation, y eventos, como MouseOver y Click. Puede consultar la
documentacin de .NET para obtener una lista completa de los miembros de la clase Control.
La luz tambin necesitar las siguientes propiedades y eventos especiales:
Propiedad Status
Determina de qu color es la luz activada. Debe ser uno de los tres siguientes tipos de valores
enumerados:
StatusRed: la luz roja est activada.
StatusYellow: la luz amarilla est activada.
StatusGreen: la luz verde est activada.
Propiedad BorderWidth
La anchura del dibujo de borde que rodea el semforo.
Evento StatusChanged
Se desencadena cuando la propiedad Status cambia a un valor distinto, mediante cdigo o clics por parte
del usuario en una luz diferente.
Puesto que estos miembros no estn en la clase base Control, ser necesario incluir el cdigo completo
para controlarlos. Tambin necesitaremos el cdigo para dibujar el semforo en la pantalla mediante el
trazado del borde y los tres crculos con los colores adecuados. Finalmente, tendremos que controlar los
clics realizados en un crculo para cambiar la luz activa y cambiar la propiedad Status cuando esto ocurra.
Para que este ejemplo est tan listo para la produccin como sea posible, tambin incluiremos un cdigo
para que el control funcione mejor con IDE de Visual Studio .NET. Le asignaremos un icono adecuado
para el cuadro de herramientas e incluiremos la lgica para que las propiedades se integren correctamente
con las ventanas Propiedades.
Comencemos.
Paso 1: creacin del tipo correcto de
proyecto
Para crear una biblioteca en la que almacenar controles de Windows Forms, inicie un nuevo proyecto en
Visual Basic .NET y seleccione el tipo de proyecto Biblioteca de controles de Windows. D al proyecto el
nombre MyControls.
En el proyecto resultante se podrn almacenar varios controles de Windows Forms, cada uno en su propia
clase. Sin embargo, slo vamos a crear un control dentro del proyecto.
Paso 2: cambio de la clase base
La clase creada en la biblioteca de controles tomar automticamente el nombre UserControl1 y, de forma
predeterminada, heredar de la clase UserControl. Sera estupendo para crear un control compuesto, ya
que bastara con empezar a arrastrar otros controles desde el cuadro de herramientas hasta la superficie
de diseo.
Sin embargo, como queremos crear nuestro propio control desde cero, tendremos que hacer algunos
cambios. Cambie el nombre de la clase del control de UserControl1 a TrafficLight. A continuacin, cambie
la lnea
Inherits System.Windows.Forms.UserControl
por esta otra:
Inherits System.Windows.Forms.Control
De esta forma, la clase ms genrica Control se convertir en la clase base. Observar que la superficie
de diseo visual ya no estar disponible y que se sustituir por una superficie de diseo de componentes.
Para mantener la coherencia del cdigo, cambie el nombre del archivo de cdigo UserControl1.vb
por TrafficLight.vb. Para ello, en el Explorador de soluciones, haga clic con el botn secundario en el
nombre del archivo de cdigo y seleccione Cambiar nombre.
Tambin necesitaremos un par de lneas de cdigo en la parte superior del mdulo de clase.
Estableceremos Option Strict en On e importaremos un espacio de nombres que contenga determinados
atributos que utilizaremos ms tarde. A continuacin se muestran las dos lneas que se deben escribir al
principio del cdigo:
Option Strict On
Imports System.ComponentModel
Paso 3: implementacin de las
propiedades y los eventos
Para implementar la propiedad Status, primero tendremos que crear una enumeracin para los posibles
valores de dicha propiedad. Inserte las lneas siguientes a continuacin de la lnea que comienza
por Inherits:
Public Enum TrafficLightStatus
statusRed = 1
statusYellow = 2
statusGreen = 3
End Enum
Esta enumeracin es pblica, es decir, los formularios que utilicen el control tendrn acceso a ella.
A continuacin de esta lneas, agregue las tres lneas siguientes:
Dim mStatus As TrafficLightStatus = TrafficLightStatus.statusGreen
Dim msngBorderWidth As Single = 1.0!
Public Event StatusChanged(ByVal NewStatus As TrafficLightStatus)
Las dos variables de las dos primeras lneas proporcionan espacio para almacenar los valores de las
propiedades Statusy BorderWidth y tambin establecen el valor predeterminado para dichas
propiedades. La variable utilizada para almacenar BorderWidth deber ser de tipo Single, ya que es el
tipo necesario para la instruccin de grficos que dibujar el borde. El signo de exclamacin en el valor
predeterminado tambin indica que es de tipo Single. La ltima lnea de este conjunto declara el
evento StatusChanged.
Introduzcamos ahora el cdigo para la propiedad BorderWidth. Inserte las lneas siguientes justo debajo
de la seccin de cdigo etiquetada como Cdigo generado por el Diseador de Windows
Forms :
<DefaultValue(1.0!), _
Description("Width of the border around the traffic light")> _
Public Property BorderWidth() As Single
Get
Return msngBorderWidth
End Get
Set(ByVal Value As Single)
If msngBorderWidth <> Value Then
msngBorderWidth = Value
Me.Invalidate()
End If
End Set
End Property
Las dos primeras lneas incluyen atributos con los que se consigue que la propiedad funcione
correctamente con el IDE. El atributo DefaultValue permite restablecer el valor de la propiedad en su
valor predeterminado en la ventanasPropiedades (posteriormente veremos cmo hacerlo). El
atributo Description proporciona el texto que aparecer en la parte inferior de la
ventana Propiedades al seleccionar la propiedad.
El atributo DefaultValue tambin tiene otras importantes ventajas. Si ubica el control TrafficLight en un
formulario y deja el valor de la propiedad BorderWidth con su valor predefinido, el diseador de
formularios no generar ninguna lnea de cdigo para establecer el valor de la propiedad. De esta forma,
se consigue que acte como otros controles de Windows Forms. Si examina el cdigo generado por el
diseador para un control tpico como TextBox, ver que slo se incluyen lneas de cdigo para
propiedades que no se establecen en sus valores predeterminados. Daremos a nuestro
control TrafficLight esta misma capacidad.
La clusula Property Get es simple. La clusula Property Set incluye una lgica que suele encontrarse
en propiedades de controles visuales. Al establecer la propiedad, es importante que el control se vuelva a
dibujar si el nuevo valor de la propiedad cambia la apariencia del control. Por tanto, la clusula
de Set comprueba si el nuevo valor que se est pasando es diferente al valor existente en la propiedad. Si
no es as, no se lleva a cabo ninguna accin. Si el nuevo valor es diferente, se acepta y, a continuacin, se
obtiene acceso al mtodo Invalidate. Este mtodo indica que el rea visual del control es obsoleta y que
se debe volver a dibujar el control.
La propiedad Status debe establecerse de forma ligeramente diferente, ya que es un valor enumerado. El
atributoDefaultValue no otorga a una propiedad enumerada la capacidad de restablecimiento
automtico. En este caso,DefaultValue no indica al diseador cundo no debe incluir el cdigo que
establece el valor de la propiedad. De esta forma, nuestra implementacin de la propiedad Status omite
el atributo DefaultValue . A continuacin se muestra el cdigo de la propiedad Status:
<Description("Status (color) of the traffic light")> _
Public Property Status() As TrafficLightStatus
Get
Status = mStatus
End Get
Set(ByVal Value As TrafficLightStatus)
If mStatus <> Value Then
mStatus = Value
RaiseEvent StatusChanged(mStatus)
Me.Invalidate()
End If
End Set
End Property
Este cdigo se asemeja bastante a la implementacin de la propiedad BorderWidth, aunque hemos
agregado algo. Cuando se cambia la propiedad Status, se desencadena el
evento StatusChanged adems de forzar que el control se vuelva a dibujar.
Para controlar el restablecimiento automtico de la propiedad en la ventana Propiedades, necesitamos
un mtodo especial. Como la propiedad se llama Status, el nombre del mtodo de restablecimiento debe
ser ResetStatus. Este mtodo simplemente devuelve a la propiedad su valor predeterminado. ste es el
cdigo:
Public Sub ResetStatus()
Me.Status = TrafficLightStatus.statusGreen
End Sub
Para avisar al diseador de cundo debe incluir una lnea de cdigo para establecer la propiedad Status,
necesitamos incluir un mtodo denominado ShouldSerializeStatus. Este mtodo devuelve un valor
booleano True cuando se necesita una lnea de cdigo para la propiedad y False cuando no es as. ste es
el cdigo:
Public Function ShouldSerializeStatus() As Boolean
If mStatus = TrafficLightStatus.statusGreen Then
Return False
Else
Return True
End If
End Function
Paso 4: dibujo de la apariencia del control
Para dar al control una representacin visual, es necesario incluir una lgica en el evento Paint. Dicha
lgica se ejecutar cada vez que se tenga que actualizar la apariencia visual del control.
En Windows Forms, la lgica de Paint utiliza clases en la parte de .NET denominada GDI+. Bsicamente,
estas clases son contenedores de las funciones grficas de la API de Windows. En .NET, son ms fciles
de usar que la API. Sin embargo, hay varios puntos que debera tener en cuenta para comprender su
funcionamiento.
En la API de Windows, las operaciones grficas necesitan un identificador de ventana, denominado a
veces hWnd. En GDI+, este identificador se sustituye por el objeto Graphics, que al mismo tiempo
representa el rea de dibujo y ofrece operaciones (mtodos) para realizar en dicha rea.
Por ejemplo, con el objeto Graphics se pueden utilizar los siguientes mtodos para dibujar diversos
elementos de la pantalla:
DrawCurve
DrawEllipse
DrawLine
DrawPolygon
DrawRectangle
DrawString
FillEllipse
FillPolygon
Estos mtodos son muy fciles de entender y representan slo una muestra de los mtodos disponibles.
Algunos mtodos ms complejos permiten, por ejemplo, girar objetos. Utilizaremos el
mtodo DrawRectangle para dibujar el borde y el mtodo FillEllipse para dibujar los crculos de
colores.
La mayor parte de los mtodos de dibujo necesitan un objeto Pen o Brush. Un objeto Pen se utiliza para
dibujar una lnea y determinar el color y grosor de sta. Un objeto Brush se usa para rellenar regiones y
determinar el color utilizado en el relleno, as como otros efectos especiales como, por ejemplo, el relleno
de la regin con un mapa de bits. Utilizaremos un efecto Brush especial para sombrear el color de las
luces que no estn encendidas.
A continuacin, se muestra el cdigo que supervisa el evento Paint del control:
Protected Overrides Sub OnPaint(ByVal pe As _
System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(pe)

Dim grfGraphics As System.Drawing.Graphics
grfGraphics = pe.Graphics

' Dibujar primero tres crculos para las luces.
' Uno estar "encendido". Los dems estarn sombreados.
DrawLight(TrafficLightStatus.statusGreen, grfGraphics)
DrawLight(TrafficLightStatus.statusYellow, grfGraphics)
DrawLight(TrafficLightStatus.statusRed, grfGraphics)

' Dibujar ahora el contorno del semforo.
' Se necesita un lpiz para dibujarlo. Ser negro.
Dim penDrawingPen As New _
System.Drawing.Pen(System.Drawing.Color.Black, msngBorderWidth)

' Dibujar el contorno del semforo en el control.
' Definir primero el rectngulo que se va a dibujar.
Dim rectBorder As System.Drawing.Rectangle

rectBorder.X = 1
rectBorder.Y = 1
rectBorder.Height = Me.Height - 2
rectBorder.Width = Me.Width - 2
grfGraphics.DrawRectangle(penDrawingPen, rectBorder)

' Eliminar los objetos de dibujo
penDrawingPen.Dispose()
grfGraphics.Dispose()

End Sub
En primer lugar, se otorga a la clase base la capacidad de pintar y bsicamente pintar el fondo con el
color correspondiente del control. A continuacin, el objeto Graphics del control se obtiene de los
argumentos del evento.
Posteriormente, se utiliza una funcin para dibujar cada uno de los tres crculos. Ms adelante trataremos
esta funcin. Observe que debemos pasar a la funcin una referencia del objeto Graphics, junto con una
indicacin del crculo que queremos dibujar (rojo, amarillo o verde).
A continuacin est el cdigo para dibujar el contorno. Se declara un rectngulo con una posicin y
tamao adecuados y, a continuacin, se pasan al mtodo DrawRectangle del objeto Graphics.
Finalmente, los objetos del dibujo tienen activado el mtodo Dispose. Con GDI+, conviene eliminar los
objetos de dibujo en cuanto haya terminado con ellos. De esta manera se limpian los recursos utilizados
por el sistema operativo para dibujar. Si el control se va a utilizar en Windows 98 o Windows Millennium
Edition, es muy importarte controlar los recursos grficos, ya que estos sistemas operativos tienen menos
capacidad para dichos recursos.
A continuacin se muestra la funcin que dibuja los crculos:
Private Sub DrawLight(ByVal LightToDraw As TrafficLightStatus, _
ByVal grfGraphics As Graphics)

Dim nCircleX As Integer
Dim nCircleY As Integer
Dim nCircleDiameter As Integer
Dim nCircleColor As Color

' Buscar la coordenada X y el dimetro de todos los crculos
nCircleX = CInt(Me.Size.Width * 0.02)
nCircleDiameter = CInt(Me.Size.Width * 0.96)
Select Case LightToDraw
Case TrafficLightStatus.statusRed
If LightToDraw = Me.Status Then
nCircleColor = Color.OrangeRed
Else
nCircleColor = Color.Maroon
End If
nCircleY = CInt(Me.Size.Height * 0.01)
Case TrafficLightStatus.statusYellow
If LightToDraw = Me.Status Then
nCircleColor = Color.Yellow
Else
nCircleColor = Color.Tan
End If
nCircleY = CInt(Me.Size.Height * 0.34)
Case TrafficLightStatus.statusGreen
If LightToDraw = Me.Status Then
nCircleColor = Color.LimeGreen
Else
nCircleColor = Color.ForestGreen
End If
nCircleY = CInt(Me.Size.Height * 0.67)

End Select
Dim bshBrush As System.Drawing.Brush
If LightToDraw = Me.Status Then

bshBrush = New SolidBrush(nCircleColor)
Else
bshBrush = New SolidBrush(Color.FromArgb(60, nCircleColor))
End If

' Dibujar el crculo para la luz de la seal
grfGraphics.FillEllipse
(bshBrush, nCircleX, nCircleY, nCircleDiameter, nCircleDiameter)

' Eliminar el pincel
bshBrush.Dispose()

End Sub
ste es el nico dibujo complejo del control. Se dibuja una elipse en GDI+ mediante la especificacin de
las coordenadas X e Y de la esquina superior izquierda del rectngulo, donde se colocar la elipse, y la
altura y anchura de dicho rectngulo. Se darn los nombres nCircleX y nCircleY a las coordenadas X e Y,
respectivamente. Puesto que estamos dibujando un crculo, la altura y la anchura del rectngulo sern la
misma y la variable nCircleDiameter se utilizar para incluir dicho valor.
nCircleX se establece para que se site justo dentro del control (la anchura del control multiplicada por
0,02). La variable nCircleY depende de la luz que se est dibujando y se establece para que se site
cerca de la parte superior del control (para la luz roja), a un tercio (para la luz amarilla) o
aproximadamente a dos tercios (para la luz verde). El dimetro, nCircleDiameter, se establece al 96%
de la anchura del control.
Lo nico que falta para dibujar una elipse rellena es seleccionar el color que deseemos utilizar.
Determinaremos el color en funcin de (1) la luz que estemos dibujando y (2) si la luz que estamos
dibujando est encendida. Los colores de la luz activa deben tener ms brillo que los de la luz inactiva.
El color se utiliza para crear un pincel para el dibujo. Si la luz que se est dibujando est activa, el color se
utilizar tal cual. Sin embargo, si la luz est inactiva, se utilizar otra forma para crear una instancia del
pincel. A continuacin se muestra la lnea de cdigo para un pincel de luz inactiva:
bshBrush = New SolidBrush(Color.FromArgb(60, nCircleColor))
ste no es uno de los mejores nombres de mtodos dados en .NET, pero el mtodo FromArgB crea un
pincel que sombrea el color mediante su combinacin con el color de fondo. El nmero utilizado como
primer argumento est comprendido entre 0 y 255 y, cuanto menor sea, ms se fundir con el fondo.
Vamos a usar un valor de 60, que atenuar considerablemente el color de la luz inactiva. Puede probar
con valores diferentes para este argumento (o convertirlo en propiedad configurable) para obtener
distintos efectos.
Finalmente, el mtodo DrawEllipse del objeto Graphics dibuja el crculo y se completa la funcin.
Recuerde que se llama a la funcin tres veces, una para cada crculo.
Paso 5: cmo hacer que el control
responda al usuario
Para que el usuario pueda cambiar el color de la luz, se deben detectar los clics que realice. Para ello,
existen varios medios, como cualquier programador con experiencia en Visual Basic sabe. Utilizaremos uno
de los ms simples, que consiste en detectar el evento MouseUp. A continuacin se muestra el cdigo
que detecta el clic del usuario y cambia la propiedad Status de forma adecuada:
Private Sub TrafficLight_MouseUp(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs)_
Handles MyBase.MouseUp
Dim nMidPointX As Integer = CInt(Me.Size.Width * 0.5)
Dim nCircleRadius As Integer = nMidPointX
If Distance(e.X, e.Y, nMidPointX, CInt(Me.Size.Height / 6)) _
< nCircleRadius Then
Me.Status = TrafficLightStatus.statusRed
Exit Sub
End If
If Distance(e.X, e.Y, nMidPointX, CInt(Me.Size.Height / 2)) _
< nCircleRadius Then
Me.Status = TrafficLightStatus.statusYellow
Exit Sub
End If
If Distance(e.X, e.Y, nMidPointX, CInt((5 * Me.Size.Height)/6))_
< nCircleRadius Then
Me.Status = TrafficLightStatus.statusGreen
End If

End Sub

Private Function Distance(ByVal X1 As Integer, _
ByVal Y1 As Integer, _
ByVal X2 As Integer, _
ByVal y2 As Integer) As Integer
Return CInt(System.Math.Sqrt((X1 - X2) ^ 2 + (Y1 - y2) ^ 2))
End Function
El control de eventos es bastante simple. Se comprueba la distancia entre la ubicacin del clic del mouse y
el centro de cada crculo. Observe que los centros de los crculos estarn a 1/6, 1/2 y 5/6 de la extensin
total del control, respectivamente. Si an no lo ve claro, dibjelo en un papel para comprobarlo. Si la
distancia calculada es inferior al radio del crculo, se cambiar la propiedad Status.
La funcin Distance calcula la distancia mediante una frmula algebraica que probablemente conocer.
Observe que la funcin para calcular la raz cuadrada se toma del espacio de nombres System.Math, en el
que se encuentran las funciones matemticas tpicas.
Paso 6: limpieza
Para que el control funcione sin problemas, se deben controlar un par de operaciones ms. Por ejemplo,
es necesario volver a dibujar el control cuando cambie de tamao. Adems, para mantener las
proporciones del control, se deben detectar los cambios en las propiedades que afectan al tamao y forzar
que la anchura sea un tercio de la altura. A continuacin se muestran las rutinas para el control de
eventos a cargo de estas tareas:
Private Sub TrafficLight_Resize(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyBase.Resize
Me.Invalidate()
End Sub

Private Sub TrafficLight_Layout(ByVal sender As Object, _
ByVal e As System.Windows.Forms.LayoutEventArgs) _
Handles MyBase.Layout
Select Case e.AffectedProperty
Case "Bounds"
Me.Width = CInt(Me.Height * 0.3333)
Case Else
' No hacer nada
End Select
End Sub
Finalmente, veamos el icono que se utilizar en el cuadro de herramientas. El control ya dispone de un
icono predeterminado que se parece a un engranaje, pero utilizaremos otro que proporciona Visual Studio
.NET que representa un semforo.
El icono del cuadro de herramientas de un control se establece con un atributo de la clase denominada
ToolboxBitmap. Inserte la siguiente lnea a continuacin de la lnea que comienza por Public Class :
<ToolboxBitmap("C:\Archivos de programa\Microsoft Visual Studio
.NET\Common7\Graphics\icons\Traffic\TRFFC09.ICO")> _
Nota Este cdigo debe incluirse en una sola lnea, se ha insertado un retorno de carro despus deStudio para
facilitar su lectura. Cuando pegue este cdigo, asegrese de que se encuentra en una sola lnea, de que hay un nico
espacio entre Studio y .NET y de que se ha eliminado el retorno de carro. De esta forma, se establecer el
atributo en un icono ubicado en el directorio de Visual Studio para el atributo, suponiendo que ha instalado Visual
Studio .NET en la ubicacin predeterminada. Si no es as, cambie la ruta al icono segn corresponda.
Paso 7: generacin y prueba del control
El control TrafficLight ya est terminado. Seleccione Generar | Generar MyControls para crear la
biblioteca de controles terminada.
Para probar el control, necesitaremos un proyecto de Windows Forms. Para ello, puede utilizar una
solucin independiente, aunque es ms fcil hacerlo en la misma solucin utilizada para desarrollar el
control. SeleccioneArchivo | Agregar proyecto | Nuevo proyecto en el men. Seleccione el tipo de
proyecto Aplicacin para Windows e introduzca TestTrafficLight como nombre del proyecto. Haga clic
en Aceptar para que la aplicacin para Windows realice la prueba.
Para poder arrastrar un control TrafficLight a Form1 en blanco para la aplicacin de prueba, antes
necesitar agregar el control TrafficLight al cuadro de herramientas. Haga clic con el botn secundario
en la ficha de Windows Forms del cuadro de herramientas y seleccione Personalizar cuadro de
herramientas. Seleccione la ficha Componentes de .NET Framework y, a continuacin, haga clic en
el botn Examinar. Busque la ubicacin del proyecto MyControlsy, a continuacin, el directorio /bin del
proyecto. Seleccione el componente MyControls.dll y haga clic en Aceptar. El cuadro de dilogo debera
ser similar al que se muestra en la figura 2.

Figura 2. Seleccin del control TrafficLight en el cuadro de dilogo Personalizar cuadro de
herramientas.
Observe que junto al control TrafficLight hay una marca de verificacin. Haga clic en el botn Aceptar. El
control TrafficLight aparecer ahora al final de la lista de controles de la ficha Windows Forms del
cuadro de herramientas. En la figura 3 se muestra un cuadro de herramientas con el
control TrafficLight situado al final.

Figura 3. Control TrafficLight al final de Toolbox
Ahora, puede arrastrar un control TrafficLight a Form1 en blanco en TestTrafficLight. De forma
predeterminada, su nombre ser TrafficLight1. Puede cambiar el tamao del control y establecer sus
propiedades, incluida la propiedadStatus, que dispondr de un men desplegable con los tres posibles
valores para dicha propiedad. Observe que a medida que cambia el tamao o las propiedades, el control
se actualiza automticamente en el diseador.
Para ver el restablecimiento de una propiedad en su valor predeterminado, cambie la
propiedad Status a statusRed. A continuacin, haga clic con el botn secundario en la
propiedad Status de la ventana Properties y seleccioneReset, como se muestra en la figura 4. La
propiedad volver a cambiar a statusGreen. El truco del restablecimiento tambin funciona con la
propiedad BorderWidth si se establece en un valor distinto de 1.

Figura 4. Opcin Restablecer para la propiedad Status en la ventana Propiedades. Observe la
descripcin de la propiedad Status en la parte inferior de la ventana.
Si lo desea, tambin puede insertar un evento StatusChanged para el control. A continuacin, podr ver
el estado modificado con esta lnea de cdigo en dicho evento:
MsgBox("New status is " &
NewStatus.ToString)
Para para realizar una prueba del control en plena accin, tendr que iniciar el proyecto TestTrafficLight.
En este momento, no es el proyecto de inicio de la solucin, as que tendr que solucionarlo. En el
Explorador de soluciones, haga clic con el botn secundario en el nombre Solution, en la primera fila.
Seleccione Propiedades y, a continuacin, cambie la configuracin Proyecto de inicio
nico de MyControls a TestTrafficLight. Haga clic enAceptar.
Presione F5 para iniciar el proyecto. Aparecer el formulario con el control TrafficLight. Para probar el
control, presione diferentes luces y observe cmo se encienden. Tambin puede realizar una prueba de la
propiedadBorderWidth e intentar establecer la propiedad Status de la luz en el cdigo.
Conclusin
Hay que admitir que el control TrafficLight es simple, aunque conoc a un programador que lo necesit
para un proyecto real. Sin embargo, muestra todos los principios necesarios para desarrollar controles ms
sofisticados, entre los que se incluyen:
La adicin de propiedades al control
La posibilidad de que las propiedades se puedan coordinar con el IDE de Visual Studio mediante valores y
descripciones predeterminados
La insercin de una lgica en el evento Paint para dibujar el control
El uso de GDI+ en la lgica de dibujo
El establecimiento de un mapa de bits para que el control se muestre en el cuadro de herramientas
La clave para crear controles ms sofisticados es familiarizarse con las capacidades de dibujo de GDI+. Si
comprende cmo TrafficLight dibuja su contorno y los crculos de colores, es un buen punto de partida.
La idea principal es que incluso los programadores perezosos como yo pueden crear controles de Windows
Forms avanzados con Visual Basic .NET.
About these ads

You might also like