2010-05-04 18 views
33

Antecedentes: Estoy personalizando una aplicación ASP .NET/C existente. Tiene su propio pequeño "marco" y convenciones que los desarrolladores deben seguir al ampliar/personalizar su funcionalidad. Actualmente estoy ampliando parte de su funcionalidad administrativa, a la cual el marco proporciona un contrato para hacer cumplir la implementación del método GetAdministrationInterface(), que devuelve System.Web.UI.Control. Este método se llama durante el método Page_Load() de la página que aloja la interfaz GUI.Los controladores de eventos de ASP .NET Button no se activan en el primer clic, sino que en el segundo clic después de un PostBack

Problema: Tengo tres botones en mi GUI, a cada uno de los cuales se le ha asignado un controlador de eventos. La GUI de mi administración se carga perfectamente, pero hacer clic en cualquiera de los botones no hace lo que espero que hagan. Sin embargo, cuando los hago clic por segunda vez, los botones funcionan.

Puse puntos de interrupción al comienzo de cada método de controlador de eventos y pasé por mi código. En el primer clic, ninguno de los controladores de eventos se activaron. En el segundo clic, dispararon.

¿Alguna idea?

Ejemplo de Botón Definición (dentro GetAdministrationInterface)

public override Control GetAdministrationInterface() 
{ 
    // more code... 

    Button btn = new Button(); 
    btn.Text = "Click Me!"; 
    btn.Click += new EventHandler(Btn_Click); 

    // more code... 
} 

Ejemplo de controlador de eventos Definición de método

void Btn_Click(object sender, EventArgs e) 
{ 
    // Do Something 
} 

Page_Load método que llama GetAdministrationInterface

protected void Page_Load(object sender, System.EventArgs e) 
{ 
    if (!Page.IsAsync) 
    { 
     List<AdministrationInterface> interfaces = <DATABASE CALL>; 
     foreach(AdministrationInteface ai in interfaces) 
     { 
      placeholderDiv.Controls.Add(ai.GetAdministrationInterface()); 
     } 
    } 
} 
+1

¿Dónde ha colocado su definición del botón y el controlador de eventos? ¿Cómo se están agregando los botones a la página? –

+0

Publique el código Page_Load que llama a 'GetAdminInterface' y crea los controles –

+0

Agregué el código' Page_Load' a la pregunta original. – John

Respuesta

62

Santo cielo! Sabía que iba a ser algo así de estúpido. Puramente mi culpa, por supuesto, y mi falta de conocimiento en ASP .NET.

Después de hacer una gran cantidad de búsquedas en Google y, finalmente, ser bloqueado por Google bajo la sospecha de ser un bot ejecutando scripts automatizados, logré exprimir en una última búsqueda y tropecé con este article. Ya a punto de darme por vencido, hice mi mejor esfuerzo para leer el artículo sin saltear 10 líneas a la vez o buscar bonitas imágenes. En la sección titulada Asignar identificadores a creado dinámicamente controles, leí estas palabras mágicas y más alegres:

Si ver el código fuente HTML antes de hacer clic en el botón de no-trabajo y después de haber hecho clic en él, notará una pequeña diferencia. Los botones tienen diferentes ID de HTML antes y después de la devolución posterior. Obtuve ctl04 y ctl05 antes del post-back y ctl02 y ctl03 después del post-back.

El botón ASP.NET reconoce los eventos al buscar un valor para su ID en la colección Request.Form. (En verdad sucede de manera diferente y los controles no comprueban la recolección de Request.Form por sí mismos. Page pasa los datos de la publicación a los controles por sus ID y a los controles que están registrados para recibir notificaciones sobre los datos de la publicación). ÁSPID.NET no activa el evento Click porque la ID del botón ha cambiado entre las publicaciones posteriores. El botón en el que ha hecho clic y el botón que ve después son botones diferentes para ASP.NET.

Efectivamente, cuando vi el HTML la primera vez, mi botón tenía la ID ctl04$ctl36. Después de hacer clic en el botón, mi botón tenía el ID ctl04$ctl33.

¡Así que ya lo tienes! Todo lo que tenía que hacer era establecer la ID en los botones y ¡listo! Mis controladores de eventos ahora están siendo llamados!

Solución muestra:

public override Control GetAdministrationInterface() 
{ 
    // more code... 

    Button btn = new Button(); 
    btn.Text = "Click Me!"; 
    // !!THE BANE OF MY EXISTENCE!! 
    btn.ID = "The_Bane_of_My_Existence"; 
    // !!THE BANE OF MY EXISTENCE!! 
    btn.Click += new EventHandler(Btn_Click); 

    // more code... 
} 

Qué gran manera de pasar dos días ...

+1

bien hecho y bien explicado. Esta es la respuesta al problema y ha guardado mi tocino. –

+0

Gran trabajo, estoy luchando para solucionar el mismo problema en los últimos 15 días. Gran artículo – Moons

+0

Awesome !!! Esta publicación fue exactamente lo que estaba buscando (durante horas). ¡Gracias! – SunfiShie

0

Si bien es difícil saber exactamente sin ver el método de carga de página completa, huele un poco como si los controladores de eventos no se conectaran hasta que la página se vuelva a cargar.

por ejemplo:

if (IsPostBack) { 
    // Add handlers here ... 
} 
1

que estaba enfrentando el mismo problema. Mi botón se congeló después de mi primer clic. Para mí, este problema molesto se resolvió cuando desactivé el atributo EnableViewState del botón.

15

Tuve el mismo problema, pero la respuesta aceptada aquí no lo estaba causando. Tenía un cuadro de texto y un botón de búsqueda, y al hacer clic en el botón la primera vez no realizó la búsqueda. El controlador de eventos del botón no estaba siendo golpeado. Pero al hacer clic en el botón por segunda vez desencadenó el evento en el servidor. He aquí por qué:

Si usted tiene una <asp:Textbox> con su conjunto AutoPostBack a true, después de escribir en el cuadro de texto y luego pasar a hacer clic en un botón, el cuadro de texto provoca un post-back inmediato el momento en que deja de estar seleccionado. Por lo tanto, el clic incluso en el botón no cuenta (la página ya está publicada como resultado del evento del cuadro de texto). Es por eso que cuando haces clic en el botón una segunda vez, funciona porque el cuadro de texto no está involucrado en la segunda publicación posterior.

Establezca la propiedad AutoPostBack del <asp:Textbox> en false para solucionar este problema.

+0

¡Gracias! Comprobé mi código y este también fue mi problema: olvidé eliminar una propiedad AutoPostBack = true del marcado de un cuadro de texto en la página aspx. Lo usé para depurar algún código de validación del lado del servidor en lugar de hacer javascript en el lado del cliente. Cuando lo eliminé, viola, el evento de clic se dispara cada vez que hago clic en el botón. Ahora el método de evento de clic de botón puede actualizar el cuadro de texto. Publicar sobre la resolución de su propio problema me ahorró horas de búsqueda adicional en línea para el problema. Grrr, odio ASP.NET, pero tengo que usarlo en el trabajo. –

5

Una solución rápida es establecer un ID para el control de su ASCX están cargando en una página. Por ejemplo, si su código es así:

 UserControl SpecsControl = (UserControl)Page.LoadControl("../name.ascx"); 
     SpecsContainer.Controls.Add(SpecsControl); 

continuación, es necesario agregar una línea (antes de Controls.Add):

  SpecsControl.ID = "Aribtrary_Name"; 

A continuación, se dispara el método de control en la primera posición.

0

Para mí fue el UpdatePanel, mi botón y mi TextBox estaban dentro de un UpdatePanel, así que cuando publiqué de nuevo, causó un comportamiento extraño. Lo tomó fuera del UpdatePanel y lo arregló.

0

Incluso tuve el mismo problema. la causa fue "localhost: 1656/secure/login.aspx? ReturnUrl =% 2f". si la solicitud contiene % 2f como cadena de consulta, la primera publicación no se realizará correctamente aunque "% 2f" representa "/".

una forma de evitar esto a través de un cheque condición en pageload

protected void Page_Load(object sender, EventArgs e) 
{ 
    string queryString = Request.QueryString.ToString(); 
    if(queryString == "ReturnUrl=%2f") 
    { 
     Response.Redirect("/secure/login.aspx"); 
    } 
} 
Cuestiones relacionadas