Compartir a través de


Tutorial: Creación de un control compuesto con C#

Los controles compuestos proporcionan un medio por el que se pueden crear y reutilizar interfaces gráficas personalizadas. Un control compuesto es básicamente un componente con una representación visual. Por lo tanto, puede constar de uno o varios controles, componentes o bloques de código de Windows Forms que pueden ampliar la funcionalidad validando la entrada del usuario, modificando las propiedades de visualización o realizando otras tareas requeridas por el autor. Los controles compuestos se pueden colocar en Formularios Windows Forms de la misma manera que otros controles. En la primera parte de este tutorial, creará un control compuesto simple denominado ctlClock. En la segunda parte del tutorial, ampliará la funcionalidad de ctlClock a través de la herencia.

Crear el proyecto

Al crear un nuevo proyecto, especifique su nombre para establecer el espacio de nombres raíz, el nombre del ensamblado y el nombre del proyecto, y asegúrese de que el componente predeterminado estará en el espacio de nombres correcto.

Para crear la biblioteca de controles ctlClockLib y el control ctlClock

  1. En Visual Studio, cree un nuevo proyecto de biblioteca de controles de Windows Forms y asígneles el nombre ctlClockLib.

    El nombre del proyecto, ctlClockLib, también se asigna al espacio de nombres raíz de forma predeterminada. El espacio de nombres raíz se usa para calificar los nombres de los componentes del ensamblado. Por ejemplo, si dos ensamblados proporcionan componentes denominados ctlClock, puede especificar el componente ctlClock mediante el ctlClockLib.ctlClock..

  2. En el Explorador de soluciones, haga clic con el botón derecho en UserControl1.cs y, a continuación, haga clic en Cambiar nombre. Cambie el nombre del archivo a ctlClock.cs. Haga clic en el botón cuando se le pregunte si desea cambiar el nombre de todas las referencias al elemento de código "UserControl1".

    Nota:

    De forma predeterminada, un control compuesto hereda de la UserControl clase proporcionada por el sistema. La UserControl clase proporciona funcionalidad necesaria para todos los controles compuestos e implementa métodos y propiedades estándar.

  3. En el menú Archivo , haga clic en Guardar todo para guardar el proyecto.

Agregar controles y componentes de Windows al control compuesto

Una interfaz visual es una parte esencial del control compuesto. Esta interfaz visual se implementa mediante la adición de uno o varios controles de Windows a la superficie del diseñador. En la siguiente demostración, incorporará controles de Windows en el control compuesto y escribirá código para implementar la funcionalidad.

Para agregar una etiqueta y un temporizador al control compuesto

  1. En el Explorador de soluciones, haga clic con el botón derecho en ctlClock.cs y, a continuación, haga clic en Diseñador de vistas.

  2. En el Cuadro de herramientas, expanda el nodo Controles comunes y, a continuación, haga doble clic en Etiqueta.

    Se agrega un Label control denominado label1 a su control en la superficie del diseñador.

  3. En el diseñador, haga clic en label1. En la ventana Propiedades, establezca las siguientes propiedades.

    Propiedad Cambiar a
    Nombre lblDisplay
    Texto (blank space)
    TextAlign MiddleCenter
    Font.Size 14
  4. En el Cuadro de herramientas, expanda el nodo Componentes y, a continuación, haga doble clic en Temporizador.

    Dado que un Timer es un componente, no tiene ninguna representación visual en tiempo de ejecución. Por lo tanto, no aparece con los controles de la superficie del diseñador, sino en el Diseñador de componentes (en una bandeja situada en la parte inferior de dicha superficie).

  5. En el Diseñador de Componentes, haga clic en timer1 y, a continuación, establezca la propiedad Interval en 1000 y la propiedad Enabled en true.

    La propiedad Interval controla la frecuencia con la que el componente Timer realiza actualizaciones. Cada vez que timer1 marca, se ejecuta el código en el evento timer1_Tick. El intervalo representa el número de milisegundos entre tics.

  6. En el Diseñador de componentes, haga doble clic en timer1 para ir al timer1_Tick evento de ctlClock.

  7. Modifique el código para que se parezca al ejemplo de código siguiente. Asegúrese de cambiar el modificador de acceso de private a protected.

    protected void timer1_Tick(object sender, System.EventArgs e)
    {
        // Causes the label to display the current time.
        lblDisplay.Text = DateTime.Now.ToLongTimeString();
    }
    

    Este código hará que la hora actual se muestre en lblDisplay. Dado que el intervalo de timer1 se estableció en 1000, este evento se producirá cada mil milisegundos, actualizando así la hora actual cada segundo.

  8. Modifique el método para que se pueda sobrescribir con la palabra clave virtual. Para obtener más información, consulte la sección "Heredar de un control de usuario" a continuación.

    protected virtual void timer1_Tick(object sender, System.EventArgs e)
    
  9. En el menú Archivo , haga clic en Guardar todo para guardar el proyecto.

Agregar propiedades al control compuesto

El control de reloj ahora encapsula un Label control y un Timer componente, cada uno con su propio conjunto de propiedades inherentes. Aunque las propiedades individuales de estos controles no serán accesibles para los usuarios posteriores del control, puede crear y exponer propiedades personalizadas escribiendo los bloques de código adecuados. En el procedimiento siguiente, agregará propiedades al control que permiten al usuario cambiar el color del fondo y el texto.

Para agregar una propiedad al control compuesto

  1. En el Explorador de soluciones, haga clic con el botón derecho en ctlClock.cs y, a continuación, haga clic en Ver código.

    Se abre el Editor de código del control.

  2. Localice la public partial class ctlClock instrucción. Debajo de la llave de apertura ({), escriba el código siguiente.

    private Color colFColor;
    private Color colBColor;
    

    Estas instrucciones crean las variables privadas que usará para almacenar los valores de las propiedades que está a punto de crear.

  3. Escriba o pegue el código siguiente debajo de las declaraciones de variables del paso 2.

    // Declares the name and type of the property.
    public Color ClockBackColor
    {
        // Retrieves the value of the private variable colBColor.
        get
        {
            return colBColor;
        }
        // Stores the selected value in the private variable colBColor, and
        // updates the background color of the label control lblDisplay.
        set
        {
            colBColor = value;
            lblDisplay.BackColor = colBColor;
        }
    }
    // Provides a similar set of instructions for the foreground color.
    public Color ClockForeColor
    {
        get
        {
            return colFColor;
        }
        set
        {
            colFColor = value;
            lblDisplay.ForeColor = colFColor;
        }
    }
    

    El código anterior hace que dos propiedades personalizadas, ClockForeColor y ClockBackColor, estén disponibles para los usuarios posteriores de este control. Las declaraciones get y set proporcionan almacenamiento y recuperación del valor de la propiedad, junto con el código para implementar la funcionalidad adecuada para las propiedades.

  4. En el menú Archivo , haga clic en Guardar todo para guardar el proyecto.

Probar el control

Los controles no son aplicaciones independientes; deben hospedarse en un contenedor. Pruebe el comportamiento en tiempo de ejecución del control y ejecute sus propiedades con el contenedor de pruebas de UserControl. Para obtener más información, vea How to: Test the Run-Time Behavior of a UserControl.

Para probar el control

  1. Presione F5 para compilar el proyecto y ejecutar el control en el contenedor de pruebas de UserControl.

  2. En la cuadrícula de propiedades del contenedor de prueba, busque la ClockBackColor propiedad y, a continuación, seleccione la propiedad para mostrar la paleta de colores.

  3. Elija un color haciendo clic en él.

    El color de fondo del control cambia al color que seleccionaste.

  4. Use una secuencia similar de eventos para comprobar que la ClockForeColor propiedad funciona según lo previsto.

    En esta sección y en las secciones anteriores, ha visto cómo se pueden combinar componentes y controles de Windows con código y empaquetado para proporcionar funcionalidad personalizada en forma de control compuesto. Has aprendido a exponer propiedades en tu control compuesto y a probarlo una vez que esté completo. En la sección siguiente aprenderá a construir un control compuesto heredado mediante ctlClock como base.

Heredar de un control compuesto

En las secciones anteriores, ha aprendido a combinar controles, componentes y código de Windows en controles compuestos reutilizables. El control compuesto ahora se puede usar como base en la que se pueden compilar otros controles. El proceso de derivar una clase de una clase base se denomina herencia. En esta sección, creará un control compuesto denominado ctlAlarmClock. Este control se derivará de su control primario, ctlClock. Aprenderá a ampliar la funcionalidad de ctlClock invalidando los métodos primarios y agregando nuevos métodos y propiedades.

El primer paso para crear un control heredado es derivarlo de su elemento primario. Esta acción crea un nuevo control que tiene todas las propiedades, métodos y características gráficas del control primario, pero también puede actuar como base para la adición de funcionalidades nuevas o modificadas.

Para crear el control heredado

  1. En el Explorador de soluciones, haga clic con el botón derecho en ctlClockLib, seleccione Agregar y, a continuación, haga clic en Control de usuario.

    Se abre el cuadro de diálogo Agregar nuevo elemento .

  2. Seleccione la plantilla Control de usuario heredado .

  3. En el cuadro Nombre , escriba ctlAlarmClock.csy, a continuación, haga clic en Agregar.

    Aparece el cuadro de diálogo Selector de herencia .

  4. En Nombre del componente, haga doble clic en ctlClock.

  5. En el Explorador de soluciones, examine los proyectos actuales.

    Nota:

    Se ha agregado un archivo denominado ctlAlarmClock.cs al proyecto actual.

Agregar las propiedades de alarma

Las propiedades se agregan a un control heredado de la misma manera que se agregan a un control compuesto. Ahora usará la sintaxis de declaración de propiedad para agregar dos propiedades al control: AlarmTime, que almacenará el valor de la fecha y hora en que se desactivará la alarma y AlarmSet, lo que indicará si se establece la alarma.

Para agregar propiedades al control compuesto

  1. En el Explorador de soluciones, haga clic con el botón derecho en ctlAlarmClock y, a continuación, haga clic en Ver código.

  2. Localice la public class instrucción. Tenga en cuenta que su control hereda de ctlClockLib.ctlClock. Debajo de la llave de apertura ( instrucción{) , escriba el código siguiente.

    private DateTime dteAlarmTime;
    private bool blnAlarmSet;
    // These properties will be declared as public to allow future
    // developers to access them.
    public DateTime AlarmTime
    {
        get
        {
            return dteAlarmTime;
        }
        set
        {
            dteAlarmTime = value;
        }
    }
    public bool AlarmSet
    {
        get
        {
            return blnAlarmSet;
        }
        set
        {
            blnAlarmSet = value;
        }
    }
    

Agregar a la interfaz gráfica del control

El control heredado tiene una interfaz visual idéntica al control del que hereda. Posee los mismos controles constituyentes que su control primario, pero las propiedades de los controles constituyentes no estarán disponibles a menos que se expongan específicamente. Puede agregar a la interfaz gráfica de un control compuesto heredado de la misma manera que agregaría a cualquier control compuesto. Para continuar añadiendo a la interfaz visual de tu reloj de alarma, agregarás una etiqueta que parpadeará cuando la alarma esté sonando.

Para agregar el control de etiqueta

  1. En el Explorador de soluciones, haga clic con el botón derecho en ctlAlarmClock y, a continuación, haga clic en Diseñador de vistas.

    El diseñador para ctlAlarmClock se abre en la ventana principal.

  2. Haga clic en la parte para mostrar del control y vea la ventana Propiedades.

    Nota:

    Mientras se muestran todas las propiedades, se atenuan. Esto indica que estas propiedades son nativas de lblDisplay y no se pueden modificar ni tener acceso a ellas en la ventana Propiedades. De forma predeterminada, los controles contenidos en un control compuesto son privatey sus propiedades no son accesibles por ningún medio.

    Nota:

    Si desea que los usuarios posteriores del control compuesto tengan acceso a sus controles internos, declárelos como public o protected. Esto le permitirá establecer y modificar las propiedades de los controles contenidos en el control compuesto mediante el código adecuado.

  3. Agregue un Label control al control compuesto.

  4. Con el mouse, arrastre el Label control inmediatamente debajo del cuadro de visualización. En la ventana Propiedades, establezca las siguientes propiedades.

    Propiedad Configuración
    Nombre lblAlarm
    Texto ¡Alarma!
    TextAlign MiddleCenter
    visible false

Adición de la funcionalidad de alarma

En los procedimientos anteriores, agregó propiedades y un control que habilitará la funcionalidad de alarma en el control compuesto. En este procedimiento, agregará código para comparar la hora actual con la hora de alarma y, si son iguales, para parpadear una alarma. Al invalidar el timer1_Tick método de ctlClock y agregar código adicional a él, ampliará la funcionalidad de ctlAlarmClock conservando toda la funcionalidad inherente de ctlClock.

Para invalidar el método timer1_Tick de ctlClock

  1. En el Editor de código, busque la private bool blnAlarmSet; instrucción . Inmediatamente debajo de esto, agregue la siguiente declaración.

    private bool blnColorTicker;
    
  2. En el Editor de código, localice la llave de cierre (})) al final de la clase. Justo antes de la llave, agregue el código siguiente.

    protected override void timer1_Tick(object sender, System.EventArgs e)
    {
        // Calls the Timer1_Tick method of ctlClock.
        base.timer1_Tick(sender, e);
        // Checks to see if the alarm is set.
        if (AlarmSet == false)
            return;
        else
            // If the date, hour, and minute of the alarm time are the same as
            // the current time, flash an alarm.
        {
            if (AlarmTime.Date == DateTime.Now.Date && AlarmTime.Hour ==
                DateTime.Now.Hour && AlarmTime.Minute == DateTime.Now.Minute)
            {
                // Sets lblAlarmVisible to true, and changes the background color based on
                // the value of blnColorTicker. The background color of the label
                // will flash once per tick of the clock.
                lblAlarm.Visible = true;
                if (blnColorTicker == false)
                {
                    lblAlarm.BackColor = Color.Red;
                    blnColorTicker = true;
                }
                else
                {
                    lblAlarm.BackColor = Color.Blue;
                    blnColorTicker = false;
                }
            }
            else
            {
                // Once the alarm has sounded for a minute, the label is made
                // invisible again.
                lblAlarm.Visible = false;
            }
        }
    }
    

    La adición de este código realiza varias tareas. La override instrucción dirige el control para usar este método en lugar del método que se heredó del control base. Cuando se llama a este método, llama al método que sobrescribe invocando la base.timer1_Tick instrucción, asegurándose de que toda la funcionalidad incorporada en el control original se replicará en este control. A continuación, ejecuta código adicional para incorporar la funcionalidad de alarma. Aparecerá un control de etiqueta parpadeante cuando se produzca la alarma.

    El control del reloj de alarma está casi completo. Lo único que queda es implementar una manera de desactivarlo. Para ello, agregará código al método lblAlarm_Click.

Para implementar el método de apagado

  1. En el Explorador de soluciones, haga clic con el botón derecho en ctlAlarmClock.cs y, a continuación, haga clic en Diseñador de vistas.

    El diseñador se abre.

  2. Agregue un botón al control . Establezca las propiedades del botón de la siguiente manera.

    Propiedad Importancia
    Nombre btnAlarmOff
    Texto Deshabilitar alarma
  3. En el diseñador, haga doble clic en btnAlarmOff.

    El Editor de código se abre en la private void btnAlarmOff_Click línea.

  4. Modifique este método para que se parezca al código siguiente.

    private void btnAlarmOff_Click(object sender, System.EventArgs e)
    {
        // Turns off the alarm.
        AlarmSet = false;
        // Hides the flashing label.
        lblAlarm.Visible = false;
    }
    
  5. En el menú Archivo , haga clic en Guardar todo para guardar el proyecto.

Usar el control heredado en un formulario

Puede probar el control heredado de la misma manera que probó el control de clase base: ctlClockpresione F5 para compilar el proyecto y ejecutar el control en el contenedor de pruebas de UserControl. Para obtener más información, vea How to: Test the Run-Time Behavior of a UserControl.

Para utilizar el control, deberá insertarlo en un formulario. Al igual que con un control compuesto estándar, un control compuesto heredado no puede estar independiente y debe hospedarse en un formulario u otro contenedor. Puesto que ctlAlarmClock tiene una mayor profundidad de funcionalidad, se requiere código adicional para probarla. En este procedimiento, escribirá un programa sencillo para probar la funcionalidad de ctlAlarmClock. Escribirá código para establecer y mostrar la AlarmTime propiedad de ctlAlarmClocky probará sus funciones inherentes.

Para compilar y agregar el control a un formulario de prueba

  1. En el Explorador de soluciones, haga clic con el botón derecho en ctlClockLib y, a continuación, haga clic en Compilar.

  2. Agregue un nuevo proyecto de aplicación de Windows Forms a la solución y asígnele el nombre Test.

  3. En el Explorador de soluciones, haga clic con el botón derecho en el nodo Referencias del proyecto de prueba. Haga clic en Agregar referencia para mostrar el cuadro de diálogo Agregar referencia . Haga clic en la pestaña con la etiqueta Proyectos. Tu ctlClockLib proyecto se enumerará bajo Nombre del proyecto. Haga doble clic en el proyecto para agregar la referencia al proyecto de prueba.

  4. En Explorador de soluciones, haga clic con el botón derecho en Prueba y luego haga clic en Compilar.

  5. En el Cuadro de herramientas, expanda el nodo Componentes de ctlClockLib .

  6. Haga doble clic en ctlAlarmClock para añadir una copia de ctlAlarmClock a su formulario.

  7. En el Cuadro de herramientas, busque y haga doble clic en DateTimePicker para agregar un DateTimePicker control al formulario y, a continuación, agregue un Label control haciendo doble clic en Etiqueta.

  8. Use el mouse para colocar los controles en un lugar cómodo en el formulario.

  9. Establezca las propiedades de estos controles de la siguiente manera.

    Supervisión Propiedad Importancia
    label1 Texto (blank space)
    Nombre lblTest
    dateTimePicker1 Nombre dtpTest
    Formato Time
  10. En el diseñador, haga doble clic en dtpTest.

    El Editor de código se abre en private void dtpTest_ValueChanged.

  11. Modifique el código para que se parezca a lo siguiente.

    private void dtpTest_ValueChanged(object sender, System.EventArgs e)
    {
        ctlAlarmClock1.AlarmTime = dtpTest.Value;
        ctlAlarmClock1.AlarmSet = true;
        lblTest.Text = "Alarm Time is " +
            ctlAlarmClock1.AlarmTime.ToShortTimeString();
    }
    
  12. En el Explorador de soluciones, haga clic con el botón derecho en Test y luego haga clic en Establecer como proyecto de inicio.

  13. En el menú Depurar , haga clic en Iniciar depuración.

    Se inicia el programa de prueba. Tenga en cuenta que la hora actual se actualiza en el ctlAlarmClock control y que la hora de inicio se muestra en el DateTimePicker control .

  14. Haga clic en el DateTimePicker donde se muestran los minutos de la hora.

  15. Con el teclado, establezca un valor para minutos que sea un minuto mayor que la hora actual que muestra ctlAlarmClock.

    La hora de la configuración de alarma se muestra en lblTest. Espere a que el tiempo mostrado llegue a la hora establecida de la alarma. Cuando la hora mostrada coincida con la hora a la que está configurada la alarma, lblAlarm parpadeará.

  16. Desactive la alarma haciendo clic en btnAlarmOff. Ahora puede restablecer la alarma.

En este artículo se ha tratado una serie de conceptos clave. Ha aprendido a crear un control compuesto mediante la combinación de controles y componentes en un contenedor de control compuesto. Ha aprendido a agregar propiedades al control y a escribir código para implementar la funcionalidad personalizada. En la última sección, ha aprendido a ampliar la funcionalidad de un control compuesto determinado a través de la herencia y modificar la funcionalidad de los métodos host reemplazando esos métodos.

Consulte también