Tutorial: Crear un componente con Visual Basic
Actualización: noviembre 2007
Los componentes proporcionan código reutilizable en forma de objetos. Una aplicación que utiliza el código de un componente para crear objetos y llamar a sus métodos y propiedades se conoce como cliente. Un cliente puede estar o no en el mismo ensamblado que el componente que utiliza.
Los procedimientos siguientes se basan los unos en los otros, así que el orden en que se ejecutan es importante.
Nota: |
---|
Los cuadros de diálogo y comandos de menú que se ven pueden diferir de los descritos en la Ayuda, en función de la configuración activa o la edición. Para cambiar la configuración, elija la opción Importar y exportar configuraciones en el menú Herramientas. Para obtener más información, vea Valores de configuración de Visual Studio. |
Crear el proyecto
Para crear la biblioteca de clases CDemoLib y el componente CDemo
En el menú Archivo, seleccione Nuevo y, a continuación, Proyecto para abrir el cuadro de diálogo Nuevo proyecto. Seleccione la plantilla de proyecto Biblioteca de clases en la lista de tipos de proyectos de Visual Basic y escriba CDemoLib en el cuadro Nombre.
Nota: Especifique siempre el nombre de un nuevo proyecto cuando lo cree. Al hacerlo se establece el espacio de nombres de la raíz, el nombre de ensamblado y el de proyecto, y también se garantiza que el componente predeterminado esté en el espacio de nombres correcto.
En el Explorador de soluciones, haga clic con el botón secundario del mouse en CDemoLib y elija Propiedades en el menú de acceso directo. Observe que el cuadro Espacio de nombres de la raíz contiene CDemoLib.
El espacio de nombres de la raíz se utiliza para calificar los nombres de los componentes del ensamblado. Por ejemplo, si dos ensamblados proporcionan componentes denominados CDemo, puede especificar el componente CDemo utilizando CDemoLib.CDemo.
Cierre el cuadro de diálogo.
En el menú Proyecto, elija Agregar componente. En el cuadro de diálogo Agregar nuevo elemento, seleccione Clase de componentes y escriba CDemo.vb.en el cuadro Nombre. Se agregará un componente denominado CDemo a la biblioteca de clases.
En el Explorador de soluciones, haga clic en el botón Mostrar todos los archivos. Abra el nodo CDemo.vb para mostrar el archivo CDemo.Designer.vb. Haga clic con el botón secundario del mouse en CDemo.Designer.vb y elija Ver código en el menú de acceso directo. Se abrirá el Editor de código.
Observe la sección Inherits System.ComponentModel.Component inmediatamente después de la clase Partial Public Class CDemo. Esta sección designa la clase desde la que se hereda nuestra clase. De forma predeterminada, un componente hereda de la clase Component proporcionada por el sistema. La clase Component proporciona muchas características al componente, entre ellas la capacidad de utilizar diseñadores.
Busque Public Sub New(). Seleccione todo el cuerpo del método y córtelo del archivo CDemo.Designer.vb presionando CTRL-X.
En el Explorador de soluciones, haga clic con el botón secundario del mouse en CDemo.vb y elija Ver código en el menú de acceso directo. Se abrirá el Editor de código.
Pegue la selección en el cuerpo de la clase CDemo. De esta forma podrá trabajar sin interferencia del diseñador.
En el Explorador de soluciones, haga clic con el botón secundario del mouse en Class1.vb y elija Eliminar. Así eliminará la clase predeterminada que se proporciona con la biblioteca de clases, ya que no se utilizará en este tutorial.
En el menú Archivo, elija Guardar todo para guardar el proyecto.
Agregar constructores y finalizadores
Los constructores controlan el modo en que se inicializa el componente; el método Finalize controla la forma en que se destruye. El código del constructor y del método Finalize de la clase CDemo mantiene un recuento actualizado del número de objetos CDemo existentes.
Para agregar código para el constructor y el finalizador de la clase CDemo
En el Editor de código, agregue variables miembro para mantener un total actualizado de las instancias de la clase CDemo y un número de identificador para cada instancia.
Public ReadOnly InstanceID As Integer Private Shared NextInstanceID As Integer = 0 Private Shared ClassInstanceCount As Long = 0
Dado que las variables miembro InstanceCount y NextInstanceID se declaran Shared, sólo existen en el nivel de clase. Todas las instancias de CDemo que tengan acceso a estos miembros utilizarán las mismas ubicaciones de memoria. Los miembros compartidos se inicializarán la primera vez que se haga referencia a la clase CDemo en el código. Puede ser la primera vez que se crea un objeto CDemo o la primera vez que se tiene acceso a uno de los miembros compartidos de la clase.
Busque Public Sub New() y Public Sub New(Container As System.ComponentModel.IContainer), los constructores predeterminados de la clase CDemo. En Visual Basic, todos los constructores se denominan New. El componente puede tener varios constructores, con diferentes parámetros, pero todos deben tener como nombre New.
Nota: El nivel de acceso de los constructores determina qué clientes podrán crear instancias de la clase. En otras versiones de Visual Basic, la creación de objetos estaba controlada por la propiedad Instancing; si utilizó la propiedad Instancing, puede que encuentre útil leer Cambios en la creación de instancias de componentes en Visual Basic.
Agregue el código siguiente a Sub New(), para incrementar el recuento de instancias cuando se cree un nueva instancia de CDemo, así como para establecer el número de identificador de instancia.
Nota: Agregue siempre el código después de la llamada a InitializeComponent. En este momento, todos los componentes constituyentes se habrán inicializado.
InstanceID = NextInstanceID NextInstanceID += 1 ClassInstanceCount += 1
Como miembro ReadOnly, InstanceID sólo se puede establecer en el constructor.
Nota: Los usuarios que conozcan la programación multiproceso observarán que la asignación InstanceID y el incremento de NextInstanceID debe ser una operación atómica. Éste y otros problemas relacionados con los subprocesos se muestran en Tutorial: Crear un componente sencillo con múltiples procesos en Visual Basic.
Agregue el método siguiente después del final del constructor:
Protected Overrides Sub Finalize() ClassInstanceCount -= 1 End Sub
El administrador de memoria llama al método Finalize inmediatamente antes de reclamar definitivamente la memoria ocupada por el objeto CDemo. El método Finalize se origina en Object, la raíz de todos los tipos de referencia de la jerarquía de clases .NET. Si reemplaza al método Finalize, puede ejecutar la limpieza inmediatamente antes de quitar el componente de la memoria. No obstante, como verá más adelante en este tutorial, existen buenas razones para liberar antes los recursos.
Agregar una propiedad a la clase
La clase CDemo sólo tiene una propiedad; se trata de una propiedad compartida que permite que el cliente averigüe cuántos objetos CDemo hay en la memoria en un momento dado. Los métodos pueden crearse de forma parecida.
Para crear una propiedad para la clase CDemo
Agregue la siguiente declaración de método a la clase CDemo con el fin de permitir que los clientes recuperen el número de instancias de CDemo.
Public Shared ReadOnly Property InstanceCount() As Long Get Return ClassInstanceCount End Get End Property
Nota: La sintaxis de declaración de propiedades es diferente de la empleada en versiones anteriores de Visual Basic. Para obtener más información sobre el cambio de sintaxis, vea Cambios en los procedimientos de propiedades para usuarios de Visual Basic 6.0.
Probar el componente
Para probar el componente, necesitará un proyecto que lo utilice. Este proyecto debe ser el primero que se inicie al presionar el botón Ejecutar.
Para agregar el proyecto de cliente CDemoTest como proyecto inicial para la solución
En el menú Archivo, seleccione Agregar y elija Nuevo proyecto para abrir el cuadro de diálogo Agregar nuevo proyecto.
Seleccione la plantilla de proyecto Aplicación para Windows, y escriba CDemoTest en el cuadro Nombre; a continuación, haga clic en Aceptar.
En el Explorador de soluciones, haga clic en CDemoTest con el botón secundario del mouse y haga clic en Establecer como proyecto de inicio en el menú de acceso directo.
Para utilizar el componente CDemo, el proyecto cliente de prueba debe incluir una referencia al proyecto de la biblioteca de clases. Después de agregar la referencia, es una buena idea agregar una instrucción Imports a la aplicación de prueba, para simplificar el uso del componente.
Para agregar una referencia al proyecto de biblioteca de clases
En el Explorador de soluciones, haga clic en el botón Mostrar todos los archivos. Haga clic en el nodo Referencias con el botón secundario del mouse inmediatamente debajo de CDemoTest, y seleccione Agregar referencia en el menú de acceso directo.
En el cuadro de diálogo Agregar referencia, seleccione la ficha Proyectos.
Haga doble clic en el proyecto de la biblioteca de clases CDemoLib. CDemoLib aparecerá bajo el nodo Referencias del proyecto CDemoTest.
En el Explorador de soluciones, haga clic en Form1.vb con el botón secundario del mouse y seleccione Ver código en el menú de acceso directo.
Si agrega la referencia a CDemoLib, podrá utilizar el nombre completo del componente CDemo, es decir, CDemoLib.CDemo.
Para agregar una instrucción Imports
Agregue la instrucción Imports siguiente en la parte superior del Editor de código para Form1, encima de la declaración Class:
Imports CDemoLib
Si agrega la instrucción Imports, podrá omitir el nombre de biblioteca y hacer referencia al tipo de componente como CDemo. Para obtener más información sobre la instrucción Imports, vea Espacios de nombres en Visual Basic.
Ahora creará y utilizará un programa para probar el componente.
Vida del objeto
El programa CDemoTest ilustrará la vida del objeto en .NET Framework mediante la creación y liberación de grandes cantidades de objetos CDemo.
Para agregar código de creación y liberación de objetos CDemo
Haga clic en Form1.vb[Design] para volver al diseñador.
Arrastre un control Button y un control Timer desde la ficha Todos los formularios Windows Forms del Cuadro de herramientas a la superficie de diseño Form1.
El componente Timer, no visual, aparece en una superficie de diseño separada, debajo del formulario.
Haga doble clic en el icono de Timer1 para crear un método de control de evento para el evento Tick. Inserte el código siguiente en el método de control de eventos.
Me.Text = "CDemo instances: " & CDemo.InstanceCount
A cada paso del temporizador, el título del formulario mostrará el recuento actual de instancias de la clase CDemo. El nombre de clase se utiliza como calificador para la propiedad compartida InstanceCount; no es necesario crear una instancia de CDemo para tener acceso a un miembro compartido.
Haga clic en la ficha Form1.vb [Diseño] para volver al diseñador.
Haga clic en Timer1 con el botón secundario del mouse y seleccione Propiedades en el menú de acceso directo. En la ventana Propiedades, establezca el valor de la propiedad Enabled en True. Esto iniciará el temporizador tan pronto como se cree el formulario.
Haga doble clic en Button, en Form1, para crear un método de control de eventos para el evento Click. Inserte el código siguiente en el método de control de eventos.
Dim cd As CDemo Dim ct As Integer For ct = 1 To 1000 cd = New CDemo Next
Es posible que este código le parezca extraño. Al crearse cada instancia de CDemo, se libera la instancia anterior. Cuando termine el bucle For, sólo quedará una instancia de CDemo. Al salir del método de control de eventos, incluso esta instancia será liberada, puesto que la variable cd quedará fuera de su ámbito.
Como ya habrá supuesto, las cosas no suceden de este modo.
Para ejecutar y depurar los proyectos CDemoTest y CDemo
Presione F5 para iniciar la solución.
Se iniciará el proyecto de cliente y se mostrará el formulario Form1. Observe que el título del formulario muestra "CDemo instances: 0".
Haga clic en el botón. El título del formulario debe mostrar "CDemo instances: 1000".
Todas las instancias de CDemo se liberaron en el momento en que terminó el procedimiento de control del evento Click del botón. ¿Porqué no finalizaron? En pocas palabras, el administrador de memoria finaliza los objetos en segundo plano, con baja prioridad. La prioridad sólo aumenta si empieza a escasear la memoria del sistema. Este esquema lento de recolección de elementos no utilizados permite asignar objetos con mucha rapidez.
Haga clic en el botón varias veces más y observe el título. En algún momento, el número de instancias se reducirá repentinamente. Esto significa que el administrador de memoria reclamó la memoria de parte de los objetos.
Nota: Si hace clic más de 10 veces y el número de instancias de CDemo no se reduce, es posible que necesite ajustar el código para que utilice más memoria. Cierre el formulario para volver al entorno de desarrollo y aumente el número de iteraciones del bucle For a 10000. A continuación, ejecute de nuevo el proyecto.
Repita el paso 3. Esta vez deberá esperar más antes de que el administrador de memoria finalice más objetos.
De hecho, cada vez que repita el paso 3, podrá asignar, probablemente, más objetos CDemo antes de que intervenga el administrador de memoria. Esto se debe a que se intercambia cada vez más memoria de Visual Studio, dejando más espacio para las instancias de CDemo.
Cierre el formulario para volver al entorno de programación.