Compartir a través de


¿Qué es un control personalizado?

En este artículo se presentan los controles personalizados y se describe cómo son diferentes de los controles de usuario. Los controles personalizados no proporcionan una superficie de diseño visual y se basan en el código proporcionado por el usuario para su representación. Esto es diferente de los controles de usuario que proporcionan una superficie de diseño visual para agrupar varios controles en una sola unidad reutilizable.

Los controles personalizados se usan cuando un control o control de usuario existente no está cerca de proporcionar la interfaz de usuario o la interactividad que necesita. Requieren más esfuerzo por su parte para implementar completamente. El manejo del teclado y el ratón sigue estando a cargo de Windows Forms, pero te corresponde implementar cualquier función o comportamiento. No hay una superficie de diseño proporcionada con un control personalizado, ya que todo el dibujo se realiza a través del código en el OnPaint método . Los componentes, como Timer, se pueden añadir a través de la superficie de diseño no visual.

Clase base

Hay dos clases base entre las que elegir al crear un control personalizado:

  • System.Windows.Forms.Control

    Esta es la misma clase base que usan otros controles de Windows Forms. Controla directamente la entrada y salida del control.

  • System.Windows.Forms.ScrollableControl

    Algunos controles de Windows Forms usan esta clase base. Esta clase extiende Control al agregar la capacidad de desplazar el contenido.

A menos que necesite desplazarse por el contenido del control personalizado, use Control como clase base.

Funcionalidades heredadas

Dado que la clase base de un control personalizado es Control, hereda automáticamente la funcionalidad de Windows Forms compartida por todos los controles. Estas son algunas de las funcionalidades que obtiene con un control personalizado:

  • Entrada de teclado y mouse.
  • Comportamientos de diseño, como anclaje y acoplamiento.
  • Compatibilidad con tabulaciones.
  • Restricciones de tamaño mínimo y máximo.

Pintura

La pintura, que implica dibujar el objeto visual del control, se logra sobrescribiendo el método OnPaint. Para obtener más información sobre cómo los controles realizan el pintado, vea Pintar y dibujar en controles.

Al crear un control personalizado mediante las plantillas de Visual Studio, el OnPaint método se invalida automáticamente. La plantilla lo hace porque es necesario escribir el código para dibujar el control. Este es un ejemplo de lo que genera la plantilla:

public partial class CustomControl1 : Control
{
    public CustomControl1()
    {
        InitializeComponent();
    }

    protected override void OnPaint(PaintEventArgs pe)
    {
        base.OnPaint(pe);
    }
}
Public Class CustomControl1

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)

        'Add your custom paint code here
    End Sub

End Class

Un control personalizado se pinta mediante el método OnPaint. El único argumento de este método es un PaintEventArgs objeto , que proporciona toda la información y la funcionalidad necesarias para representar el control. PaintEventArgs proporciona dos propiedades que se usan en la representación del control:

  • PaintEventArgs.ClipRectangle: representa la parte del control que debe volver a dibujarse. Puede tratarse del control completo o de una parte del control.

  • Graphics: representa la superficie gráfica del control. Proporciona varios objetos y métodos orientados a gráficos que ofrecen la funcionalidad necesaria para dibujar su control.

Se llama al OnPaint método cada vez que se dibuja o actualiza el control en la pantalla, y el PaintEventArgs.ClipRectangle objeto representa el rectángulo en el que tiene lugar el dibujo. Si es necesario actualizar todo el control, PaintEventArgs.ClipRectangle representa el tamaño de todo el control. Si solamente es necesario actualizar una parte del control, representa únicamente la región que debe ser redibujada. Un ejemplo de este tipo de caso sería cuando otro control de la interfaz de usuario oculta parcialmente un control y ese otro control se aleja, la parte recién expuesta del control subyacente debe volver a dibujarse.

El código en el método OnPaint de un control se ejecuta cuando el control se dibuja por primera vez y cada vez que se invalida. Para asegurarte de que el control se vuelve a dibujar cada vez que se cambia el tamaño, agrega la siguiente línea al constructor de tu control:

SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.ResizeRedraw, True)

Ejemplo

El siguiente fragmento de código es un control personalizado que representa varios rectángulos de color alrededor del borde del control.

protected override void OnPaint(PaintEventArgs pe)
{
    Rectangle rect = this.ClientRectangle;

    // Bring the width/height in by 1 pixel so the rectangle is drawn inside the control.
    // Otherwise, it kind of overlaps the outside edge.
    rect.Width -= 1;
    rect.Height -= 1;

    Pen[] colorPens = new Pen[] { Pens.Blue, Pens.BlueViolet,
                                  Pens.AliceBlue, Pens.CornflowerBlue,
                                  Pens.Cyan, Pens.DarkCyan };

    foreach (Pen pen in colorPens)
    {
        pe.Graphics.DrawRectangle(pen, rect);
        rect.Inflate(-1, -1);
    }

    // Raise the Paint event so users can custom paint if they want.
    base.OnPaint(pe);
}
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)

    Dim rect As Rectangle = Me.ClientRectangle

    'Bring the width/height in by 1 pixel so the rectangle is drawn inside the control.
    'Otherwise, it kind of overlaps the outside edge.
    rect.Width -= 1
    rect.Height -= 1

    Dim colorPens As Pen() = {Pens.Blue, Pens.BlueViolet,
                                Pens.AliceBlue, Pens.CornflowerBlue,
                                Pens.Cyan, Pens.DarkCyan}

    For Each curPen As Pen In colorPens

        e.Graphics.DrawRectangle(curPen, rect)
        rect.Inflate(-1, -1)

    Next

    'Raise the Paint event so users can custom paint if they want.
    MyBase.OnPaint(e)

End Sub

El código anterior crea un control similar a la siguiente imagen:

Un control personalizado como se representa en Visual Studio. El control es un cuadro vacío con diferentes colores bordeándolo. Cada color se establece en un solo píxel.

Contexto

Observe que el fondo del control se pinta con el SystemColors.Control color, aunque el OnPaint código no borre o rellene el control con un color. El fondo se pinta realmente mediante el método OnPaintBackground(PaintEventArgs) antes de llamar a OnPaint. Invalide OnPaintBackground para controlar el dibujo del fondo del control. La implementación predeterminada de este método es dibujar el color y la imagen establecidos por las BackColor propiedades y BackgroundImage , respectivamente.