Crear controles personalizados (NumericTextBox) – Windows Forms

Los controles de los formularios Windows Forms son componentes reutilizables que encapsulan funciones de la interfaz de usuario y se utilizan en aplicaciones Windows cliente, los controles existentes también se pueden combinar entre sí o ampliar.

Resultado final de nuestros controles personalizados.Supongamos que estamos desarrollando una aplicación donde se requiere que en varios formularios el usuario solo ingrese números o que se requiere que ingrese números con decimales, en los controles que nos ofrece el entorno de desarrollo no encontramos ninguno que nos de esta posibilidad. Para dar solución a nuestra necesidad tenemos otras opciones como buscar componentes (paquetes de controles) que incluyan este tipo de controles como Infragistic (NetAdvantage for Windows Forms Controls) o DotNetBar for Windows Forms (componentes que nos sirven para crear aplicaciones atractivas), pero, son de pago y este puede ser un inconveniente si solo necesitamos un control, para ello la solución es crearnos un control personalizado de la clase TextBox, empecemos entonces.

Empezamos creando nuestro proyecto de C# seleccionando plantillas de Windows y seleccionamos el tipo Biblioteca de controles de Windows Forms.

Por default nos crea un control de usuario que vemos en el diseñador, si se tratara de crear un control de usuario aquí agregaríamos controles para formar nuestro control de usuario, pero en esta ocasión no es el caso, lo que queremos es crear un control TextBox que solo acepte números, así que cambiamos el nombre de nuestro archivo creado por defecto asignándole el nombre que le daremos a nuestro control como NumericTextBox como se ve en la imagen.

Abrimos el código fuente de nuestro control y cambiamos la herencia, por default nuestra clase creada hereda la clase UserControl, pero como queremos crear un TextBox personalizado, entonces cambiamos la herencia a la clase TextBox, esto hará que nuestra clase herede todas las propiedades, métodos y eventos de la clase TextBox, después de realizado esto, el diseñador ya no permitirá agregar controles.

Ahora abrimos el código del diseñador como se ve en la imagen y eliminamos al línea de código:
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; ya que no esta propiedad no existe en el control TextBox.

Volvemos al código fuente de nuestra clase NumericTextBox y agregamos dentro de ella el método que sobrescribirá el método OnKeyPress de la clase TextBox, en el nuestro, agregaremos el código que solo permita el ingreso de números y permita al usuario utilizar las teclas de control (Inicio, Fin, Suprimir, Retroceso).

//Sobreescribir el metodo OnKeyPress de la clase TextBox
protected override void OnKeyPress(KeyPressEventArgs e)
{
//solo permitir numeros y teclas de control
if (Char.IsDigit(e.KeyChar) || Char.IsControl(e.KeyChar))
{
e.Handled = false; //permitir el caracter
}
else
{
e.Handled = true; //rechazar el caracter
}
}

Hasta aquí, ya hemos personalizado nuestra clase, ahora vamos a verificar que funcione, para ello agregamos un proyecto de Aplicación de Windows Forms a nuestra solución y lo establecemos como proyecto de inicio.

Generaremos el ensamblado de nuestro proyecto MisControles, para ello solo damos clic derecho sobre nuestro proyecto y seleccionamos Generar (solo compila el proyecto sin ejecutarlo).

Ahora en el cuadro de herramientas podemos encontrar ya nuestro nuevo control, podemos agregarlo al formulario de nuestro nuevo proyecto, este se verá idéntico al TextBox Control.

Y simplemente ejecutamos nuestra aplicación y verificamos que efectivamente nuestro control NumericTextBox solo acepta números.

Bien, hasta aquí ya está nuestro nuevo control TextBox que solo acepta número y se llama NumericTextBox, este nuevo control podemos utilizarlo en cualquier aplicación cliente que desarrollemos, para ello podemos agregarlo como un control más al cuadro de herramientas. Agregamos una nueva ficha en el cuadro de herramientas llamada Mis Controles haciendo clic derecho sobre el cuadro de herramientas.

Para agregar nuestro control damos clic derecho sobre nuestra nueva ficha / Elegir elementos, dando clic en el botón Examinar de la ventana que se nos muestra, buscamos el ensamblado (archivo ControlesPersonalizados.dll generado) de nuestro proyecto ControlesPersonalizados en la carpeta de nuestro proyecto/bin/Debug.
.

Ya seleccionado el ensamblado haciendo clic en abrir y aceptar en las ventanas abiertas, podemos ver en nuestra nueva ficha que ya se encuentra el nuevo control (si un ensamblado contiene más de 1 control, estos se agregan automáticamente (si no se desactiva la selección en la ventana de seleccionar elementos)).

Puede parecernos que el icono que aparece no es atractivo, así que podemos especificar el icono que este debe mostrar, para ello, volvemos al código fuente de nuestra clase NumericTextBox y agregamos el siguiente fragmento de código [ToolboxBitmap(typeof(TextBox)) antes de la declaración de la clase para quedar así.

[ToolboxBitmap(typeof(TextBox))]
public partial class NumericTextBox : TextBox
{

Con esto estamos especificando que nuestro control adopte el icono de la clase TextBox. Ahora eliminamos el control de nuestra nueva ficha haciendo clic derecho sobre el control NumericTextBox y elegimos eliminar.
Volvemos a generar la solución entera o solo el proyecto ControlesPersonalizados y volvemos a agregar el control a nuestra ficha donde ahora podemos ver que nuestro control ha adoptado el icono del TextBox control.

Si quisiéramos que nuestro control tenga un icono que represente que solo acepta números, tenemos que buscar o diseñar el icono adecuado, y antes de la declaración de la clase cambiaríamos [ToolboxBitmap(typeof(TextBox))] por [ToolboxBitmap(@”D:\afelipelcDocs\images\NumericTextbox.bmp“)] donde especificamos la ruta de la imagen de mapa de bits que debe mostrar y al volver a agregar nuestro control al cuadro de herramientas (antes eliminarlo primero) ahora tendríamos esto:

Hasta aquí termina esta parte de crear un control personalizado básico, ya después crearemos otro ejemplo que permita solo números con decimales, que será muy similar a este.

Código fuente del ejemplo: Codigo del ejemplo ControlesPersonalizados (Nota: WordPress.com no admite el tipo de archivo .zip, por esta razón cambie la extensión del archivo, guarda el archivo controlespersonalizados.pdf en tu pc y cambia al extensión PDF a ZIP, desempaqueta y listo).

Referencias:
Fundamentos de desarrollo de controles de formularios Windows Forms.
Desarrollo de controles personalizados
Heredar de un control de formularios Windows Forms con Visual C#
Proporcionar un mapa de bits del cuadro de herramientas para un control

Calificar esta entrada:

Anuncios

2 comentarios en “Crear controles personalizados (NumericTextBox) – Windows Forms

  1. Hola.

    Tu ejemnplo es muy basico la verdad, a mi me gustaria poder cambiar la apariencia del textbox por ejemplo, pero no solo del textbox, sino de todos los componentes, solo eso, validaciones y cosas asi las haria como siempre, solo quiero que el control se vea diferente, entonces, se que es en el evento onpaint, pero lo que no se, es como funciona este evento para cada clase (textbox, datetimepicker,datagridview, etc), entonces, la pregunta es, de donde puedo sacar el codigo original del componente para poder sobreescribir el evento onpaint e ir moviendo poco a poquito lo que hay dentro de este evento hasta conseguir el efecto que quiero.

    Gracias y disculpa la molestia.

  2. Para implementar una propiedad llamada Value que devuelva el valor que contiene el cuadro de texto pero como tipo de dato entero y ocultar la propiedad Text en la ventana de propiedades seria:

    //Ocultar la propiedad Text
    [Browsable(false)]
    public override string Text
    {
    get
    {
    return base.Text;
    }
    set
    {
    base.Text = value;
    }
    }

    //Implementar la propiedad Value

    private int valor; //campo que almacene el valor entero

    [Description(“Obtiene o establece el valor entero del cuadro de texto numerico.”)]
    public int Value
    {
    get
    {
    if(this.Text != “”)
    valor = Convert.ToInt32(this.Text);

    return valor;
    }
    set { valor = value;

    if(valor!=0)
    this.Text = valor.ToString();
    }
    }

Escribe tu comentario:

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s