OnClick Event not fired first in custom control

Tal y como indica el título de este post, voy a explicar porque a veces no se ejecuta el evento 'OnClick' a la primera, dentro de nuestros Custom controls, y sí a la segunda.

El problema supuesto se puede reproducir insertando en una página aspx, varios controles personalizados, que a su vez tienen subcontroles hijos personalizados con botones que deben ejecutar un postback a la página padre.

Contemos con el supuesto inicial:
· Una página padre, con un UpdatePanel de Ajax.
· Un control principal, que se inserta 5 veces en la página padre.
· Unos controles hijos que se insertan dinámicamente en el control padre (segun la interaccion del usuario), hasta un total de 3.
· Estos controles hijos tienen un botón que permite eliminarlos de la lista del control padre.

El proceso es el siguiente:
Cuando se carga la página principal, el usuario puede añadir los controles padre según le convenga. Además, según se van cargando los controles padres, el usuario puede ir insertando en ellos, los controles hijos. Si en algún momento se encuentra en la necesidad de borrar un subcontrol hijo de la lista de uno de los padres, debe pulsar su botón para eliminarlo... y es en este punto donde falla el sistema si se han añadido más de un control hijo.

Después de mucho buscar en "San Google" (más adelante pondré algunas referencias) en la mayoría de los supuestos, se hablaba de un conflicto con los postback, y la carga de los controles de forma asíncrona. O bien, trataban el tema desde la generación de los controles en el Page_Load.

Teniendo en cuenta las anteriores soluciones y confirmando que todo estaba en su sitio, encontré mi propia solución y tuve que darme golpes contra la pared porque se trataba de un tema tan simple como abrumador.

SOLUCION:

El propio compilador de ASP.NET, genera un ID automático y único para cada componente insertado en la página, sin importar cuando o donde se genere. Ahora bien, si se insertan dinámicamente los controles, es posible que por el orden de inserción, dichos controles no contengan el mismo ID entre un postback y otro.

Esto supone, que si insertamos un primer control e inmediatamente después, realizamos un postback sobre él, el sistema es capaz de reconocer de dónde viene, y por tanto ejecutarlo. Pero si por el contrario, insertamos un primer elemento y posteriormente un segundo, es posible que los ID autogenerados entren en conflicto y al intentar realizar un postback desde el primero, éste no encuentre el ID inicial y no ejecute el evento.

NOTA CURIOSA: En este punto la página ha vuelto a reenviarse y cada subcontrol se ha vuelto a generar con un nuevo ID. Por tanto si se vuelve a ejecutar el postback del botón, esta vez SÍ encontrará el control y lo realizará correctamente.

COMO EVITAR ENTONCES este problema...
Tan sencillo como estúpido. Asigna directamente un ID único a tu subcontrol cuando lo generes. De esta forma mantendrá siempre un identificador unico por muchos controles que insertes en la página.

Entiendo que algunos me podréis decir que es "Good Practice" asignar directamente el ID y sí, así es. Pero el problema es que muchas veces necesitamos trabajar tan rápido, y estamos tan acostumbrados a las bondades de Visual Studio, que nos olvidamos de estos pequeños detalles (tan importantes).

Así que no lo olvides, toma como buena práctica identificar cada control que generes con un ID propio, y evitarás este molesto ¿problemilla?.

Espero que os ayude.
¡Un saludo a todos!

Referencias:
StackOverflow Questions: 2765815
PostBack forced on UpdatePanel
Programmatically adding ASP.net User Control to Partial Page Update / UpdatePanel

1 comentario:

  1. Sigue así Rafa, es el tipo de material que nos viene bien a todos.
    Gracias.

    ResponderEliminar