Tal y como promet铆 en un anterior post, voy a explicar c贸mo podemos conseguir que un control sea utilizable directamente por los controles de validaci贸n est谩ndar que vienen con ASP.NET.

Ciertos controles Web (por ejemplo el control Calendar) no permiten su uso combinado con los controles de validaci贸n (estilo RequiredFieldValidator, RangeValidator, etc...), lo cual es una l谩stima porque para poder validar su contenido tenemos que construir nuestro propio control de validaci贸n (en fin...) o bien usar eventos de servidor para poder validarlos. Una de las ventajas de los controles de validaci贸n de ASP.NET es que ya realizan una validaci贸n en el cliente adem谩s de la que se hace en el servidor despu茅s, lo que ahorra tiempo y agiliza mucho la interfaz. Adem谩s est谩n integrados en la validaci贸n de la p谩gina y permiten comprobar la propiedad IsValid de 茅sta antes de continuar con suprocesamiento, algo muy 煤til tambi茅n.

Por otro lado es muy habitual combinar diversos controles Web con una prop贸sito com煤n dentro de un control de usuario (.ascx) de forma que podamos reutilizarlos en cualquier lugar de la interfaz. Al igual que (como hemos visto), por defecto, no tienen un m茅todo para establecer su foco, tampoco es posible usarlos con los validadores est谩ndar, por lo que pierden parte de su utilidad al no poder usarlos del mismo modo que los controles m谩s habituales.

Ser铆a interesante poder a帽adir la capacidad de trabajar con los controles de validaci贸n a este tipo de controles. Vamos a ver c贸mo conseguirlo.

Un ejemplo real

Por ejemplo, imagina un control ASCX de selecci贸n espec铆fico de nuestra aplicaci贸n. 脡ste contiene un par de listas desplegables para seleccionar elementos desde la base de datos, una lista de elementos vac铆a inicialmente y un bot贸n que permite a帽adir elementos a esta lista para su selecci贸n. Queremos colocar este control en cualquier formulario y que nos sirva, por ejemplo, para seleccionar localidades de un pa铆s. Su aspecto ser铆a similar a este:

Este control de la imagen es uno real, usado en diversos lugares de la aplicaci贸n de uno de nuestros clientes para permitir la selecci贸n de zonas y 谩reas geogr谩ficas relacionadas. Tiene una funcionalidad relativamente compleja que implica el uso de bases de datos, validaci贸n de los datos seleccionados, etc... En algunos lugares de la aplicaci贸n se permite su uso de forma que no es obligatoria la selecci贸n de elementos (por ejemplo para las b煤squedas, ya que si no se indica zona alguna no se restringe por dicha dimensi贸n), y en otras zonas es necesario validar que se haya seleccionado como m铆nimo una zona, o incluso m谩s de una.

Con el control creado de la manera habitual, al colocarlo en un formulario no podemos utilizar los controles de validaci贸n con 茅l, por lo que no nos quedar铆a m谩s remedio que responder a un evento de servidor (por ejemplo a la pulsaci贸n del bot贸n de la acci贸n principal del formulario), hacer la comprobaci贸n pertinente y mostrar un mensaje en el cliente con una etiqueta, con lo que no se integrar铆a con la validaci贸n de los restantes controles.

A帽adiendo la funcionalidad de validaci贸n

Para que un control pueda ser validado por un validador com煤n debe implementar alguna propiedad de tipo texto que devuelva un valor interpretable por el validador. Normalmente deber铆amos hacer que devolviera una cadena vac铆a en caso de no contener un valor correcto y as铆 funcionar谩 bien con el RequiredFieldValidator.

En nuestro caso hemos definido la propiedad NumItems del control ASCX que simplemente indica el n煤mero de zonas seleccionadas en el control en un momento dado:

public string NumItems
{
  get 
  {
    if (lstSeleccion.Items.Count > 0)
      return lstSeleccion.Items.Count.ToString();
    else
      return String.Empty;
    }
}

Una vez definida esta propiedad debemos indicar al runtime de ASP.NET que ser谩 茅sta la utilizada para realizar las validaciones. ello se consigue usando el atributo ValidationProperty. 脡ste toma como par谩metro el nombre de la propiedad a utilziar en las validaciones, por lo que en la definici贸n de nuestra clase escribimos:

[ValidationProperty("NumItems"), SupportsEventValidation]
public partial class Controles_SelectorZonas : System.Web.UI.
UserControl
{

As铆 indicamos que los validadores deben usar la propiedad NumItems para realizar la validaci贸n. El otro atributo, SupportsEventValidation, se utiliza para indicar al runtime que nuestro control soporta los eventos de validaci贸n ya qe de otra forma no se generar铆an eventos de validaci贸n.

Nota: Si quisi茅semos hacer algo similar con un control est谩ndar que no soporte validaci贸n, como el calendario, tendr铆amos que crear una nueva clase que heredara de 茅ste y decorarla con este atributo para poder usarlo.

Vale. Listo. Si ahora soltamos el control en un formulario Web y a帽adimos un control de validaci贸n veremos que... 隆no aparece nuestro control en la lista de los controles que podenmos utilizar! :-(

No pasa nada. Es un peque帽o efecto secundario. Simplemente a帽ad谩moslo a mano en el atributo ControlToValidate del validador y veremos que funciona correctamente. Por ejemplo:

<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="lstDestinos"
CssClass="ErrorMsg" Display="Dynamic" ErrorMessage="Debe seleccionar al menos una zona de destino."></asp:RequiredFieldValidator>

El valor del atributo ControlToValidate, que es el nombre del control ascx que queremos validar, lo hemos metido a mano, pero funciona  perfectamente que es lo que busc谩bamos. Ahora nuestro complejo control de usuario se integra bien en la estructura de validaci贸n de la pa麓gina y podemos trabajar con 茅l como con cualquier otro control validable.

Super-煤til 驴no? :-)

💪🏻 驴Este post te ha ayudado?, 驴has aprendido algo nuevo?
Pues NO te pido que me invites a un caf茅... Te pido algo m谩s f谩cil y mucho mejor