Dotando a los controles de .NET de un borde personalizado

Sorprendentemente los controles de .NET no admiten apenas estilos de borde. Por ejemplo el control listbox solo permite dibujar el borde de tres formas: hundido, con una línea negra o sin borde.

El intellisense que desarrollé hace tiempo para el editor de código se basaba en un listbox y no tenía una apariencia adecuada ni similar a los del intellisense de los IDES habituales debido al borde que tenía que era el borde hundido que viene por defecto en dicho control.

La primera forma de implementar los bordes que me vino a la cabeza fue crear un control que heredara de listbox, es la forma más lógica de implementarlo debido a lo que se busca es un listbox con cierta funcionalidad adicional. Sin embargo el control listbox no implementa el evento paint y aunque lo hereda de la clase Control nunca se levanta. De igual forma si se sobrescribe el método onpaint tampoco se ejecuta nunca.

La siguiente opción que se me ocurrió fue crear un control de usuario compuesto de un listbox y un picturebox, un panel o similar que contuviera el listbox y que sobresaliera dos pixels por cada uno de los lados del listbox. En esos pixeles sería donde dibujaría los bordes valiéndome del evento paint. Esta opción tiene un importante inconveniente y es que al no heredar de listbox sino de la clase UserControl no implementa todos los métodos, propiedades y eventos de listbox. En este punto habría dos opciones, la fácil que consistiría en hacer publico el listbox. Esta opción rompe con uno de los pilares de la orientación a objetos que es la encapsulación y el código que utilizara el control tendría que hacer utilizar por ejemplo listBoxConBorde.ListboxInterno.SelectedIdex en vez de listBoxConBorde.SelectedIdex que sería lo deseable.
La otra opción sería recubrir las propiedades, métodos y eventos del listbox en el control de usuario, creando en el control de usuario tantas propiedades, métodos y eventos como tenga el listbox. Estos miembros del control de usuario simplemente llamarían a los miembros homónimos del listbox. Esta opción me parece más adecuada que la anterior pero mucho mas tediosa de implementar.

Finalmente opté por una solución que me ha parecido mucho más acertada, sencilla y genérica. Consiste en crear un control llamado “Borde” que dibuje el borde de cualquier control. Hereda de la clase “Control” y consta de dos propiedades:

  • El tipo de borde (que admite los siguientes valores Elevado, ElevadoDobleLinea, Hundido, ElevadoYHundido y HundidoYElevado)
  • El control asociado al que se le dibujará el borde.

Además del código para realizar el dibujo del borde también se encarga de adecuar su tamaño y posición a la del control asociado.

Extender el control para añadir nuevos tipos de bordes con diferentes efectos sería una labor bastante sencilla de realizar.

La nueva apariencia del intellisense estableciendo el borde a ElevadoDobleLinea es la siguiente:


Intellisense con el nuevo borde.
Intellisense con el nuevo borde.


Intellisense."
Intellisense anterior.

 

En la sección de descargas se puede encontrar el código completo en VB.NET del control.

Leave a Reply

Antispam. Escriba la palabra 'hola' (sin comillas)