2010-07-06 11 views
11

En una página que tengo:botón para hacer clic dos veces en asp.net (después de texto AutoPostBack)

<asp:TextBox runat="server" ID="EmailTextBox" AutoPostBack="true" OnTextChanged="EmailTextBox_Changed" /> 
<asp:Button runat="server" ID="SearchButton" OnClick="AddButton_Click" Text="add" /> 

En EmailTextBox_Changed, que cuenta hasta cuántos correos electrónicos se pueden encontrar, antes de ejecutar la búsqueda.

El problema es que cuando escribe algo en EmailTextBox y hace clic en el botón, debe hacer clic dos veces para obtener los resultados reales. Esto se debe a que el primer clic está haciendo la parte "AutoPostBack" del cuadro de texto, y luego debe hacer clic de nuevo para que se realice la devolución de clic.

Sin eliminar el "AutoPostBack = true", ¿cómo puedo evitar que necesite dos clics en estas circunstancias?

+0

-Cambiar el botón de un control de servidor a un botón de cliente basado, además, usa JS para esto – JonH

Respuesta

1

Por lo que es un cheque lado del cliente era la solución a esto ... no parece ser una forma de evitar que de otro modo

1

De hecho, no tiene que hacer clic en el botón para que suceda el primer evento. Simplemente 'deja' el cuadro de texto, es decir, con 'tabbing' fuera de él para que ocurra el AutoPostBack.

Si desea hacer ambas cosas en una sola devolución, simplemente elimine el botón y haga lo que hace en AddButton_Click también en el evento Textbox_Change.

+0

Hm sí, quizás. Quise tratar de evitar eso ya que en el cuadro de texto uno solo hace una cuenta, y el botón hace una búsqueda completa. – Paul

0

Puede evitar esto no haciéndolo desde el lado del servidor y usando Javascript. Tampoco publicaste tu evento de carga de página. ¿Estás revisando si publica o no?

Otra forma de hacerlo es que el evento que ocurre al hacer clic en el botón se puede invocar desde el evento TextChanged y deshacerse del botón al mismo tiempo.

+0

Hm sí, lo consideré. En realidad, hay más cuadros de texto, y el autopostback está allí para que pueda ver un recuento de los resultados a medida que los filtra, y cuando esté listo, puede mostrarlos. Tal vez una solución totalmente javascript es el camino a seguir. – Paul

2

que estaba buscando una respuesta a este problema también. Terminé eliminando todo autopostback = true y haciendo todas las acciones con JavaScript, igual que tú.

Sin embargo, una de las cosas con las que experimenté antes de JavaScript era mantener el control después de una devolución de datos. Noté que el campo oculto que utilicé para almacenar el nombre del control que tenía el último foco tenía el nombre del botón de búsqueda (el mío es un botón de guardar). Así que, aunque todavía no estoy seguro de cómo hacer que la función de "búsqueda" se active "automáticamente" como debería, que es básicamente encadenar los eventos de devolución tanto del cuadro de texto como del botón, uno tras otro, PUEDO saber que el usuario hizo clic en ese botón de guardar antes de que la devolución de datos sucediera (o lo intentó).

Por lo tanto, lo que tiene en la devolución es la activación del evento de cuadro de texto y luego el método Page_Load, o cualquier método de ciclo de página que desee usar, donde puede verificar qué control tuvo el último control. Con esto, hay varias maneras en que podrías implementar una solución alternativa.

Off lado, se podría añadir el código en cada evento que dispara a un AutoPostBack de control, como el cuadro de texto y el botón de búsqueda, para comprobar el nombre del control de enfoque. Si el control que tenía el último foco NO es la función de autopostback del control que estamos ejecutando, podemos establecer un bool de nivel de página llamado 'Run_Controls_Method' en TRUE, de lo contrario, establézcalo en falso. De esta forma, sabemos que debemos ejecutar el control que tenía el último método de devolución de foco.

al cargar la página, usted podría hacer algo como:

if (Run_Controls_Method && hdfFocusControl.Value != "") 
{ 
    switch(hdfFocusControl.Value) 
    { 
     case "btnSearch": 
      btnSearch_OnClick(null, null); 
      break; 
     case etc. 
    } 
} 

A mi modo de poner en práctica el hdfHasFocus es:

HTML:

<input id="hdfHasFocus" runat="server" type="hidden" /> 

código HTML detrás:

protected void Page_PreRender(object sender,EventArgs e) 
{ 
    if (IsPostBack != true) 
    { 
     //Add the OnFocus event to all appropriate controls on the panel1 panel.   
     ControlManager.AddOnFocus(this.Controls,hdfHasFocus,true); 
     //other code... 
    } 

    ControlManager.SetFocus(this.Controls,hdfHasFocus.Value,true); 
} 

Control Manager.cs código relacionado:

 /// <summary> 
    /// Adds the onfocus event to the UI controls on the controls in the passed in control list. 
    /// </summary> 
    /// <param name="controls">The list of controls to apply this event.</param> 
    /// <param name="saveControl">The control whose .value will be set to the control.ID of the control which had focus before postback.</param> 
    /// <param name="Recurse">Should this method apply onfocus recursively to all child controls?</param> 
    public static void AddOnFocus(ControlCollection controls, Control saveControl, bool Recurse) 
    { 
     foreach (Control control in controls) 
     { 
      //To make the .Add a bit easier to see/read. 
      string action = ""; 

      //Only apply this change to valid control types. 
      if ((control is Button) || 
       (control is DropDownList) || 
       (control is ListBox) || 
       (control is TextBox) || 
       (control is RadDateInput) || 
       (control is RadDatePicker) || 
       (control is RadNumericTextBox)) 
      { 
       //This version ignores errors. This results in a 'worse case' scenario of having the hdfHasFocus field not getting a 
       // value but also avoids bothering the user with an error. So the user would call with a tweak request instead of 
       // and error complaint. 
       action = "try{document.getElementById(\"" + saveControl.ClientID + "\").value=\"" + control.ClientID + "\"} catch(e) {}"; 

       //Now, add the 'onfocus' attribute and the built action string. 
       (control as WebControl).Attributes.Add("onfocus", action); 
      } 

      //The 'onfocus' event doesn't seem to work for checkbox...use below. 
      if (control is CheckBox) 
      { 
       //This version ignores errors. This results in a 'worse case' scenario of having the hdfHasFocus field not getting a 
       // value but also avoids bothering the user with an error. So the user would call with a tweak request instead of 
       // and error complaint. 
       action = "try{document.getElementById(\"" + saveControl.ClientID + "\").value=\"" + control.ClientID + "\"} catch(e) {}"; 
       //In case there is already an attribute here for 'onclick' then we will simply try to add to it. 
       action = action + (control as WebControl).Attributes["onclick"]; 

       //Now, add the event attribute and the built action string.     
       (control as WebControl).Attributes.Add("onclick", action); 
      } 

      //You don't seem to be able to easily work the calendar button wiht the keyboard, and it seems made for 
      // mouse interaction, so lets set the tab index to -1 to avoid focus with tab. 
      if (control is CalendarPopupButton) 
      { 
       (control as WebControl).Attributes.Add("tabindex", "-1"); 
      } 

      //We also want to avoid user tab to the up and down spinner buttons on any RadNumericTextBox controls. 
      if (control is RadNumericTextBox) 
      { 
       (control as RadNumericTextBox).ButtonDownContainer.Attributes.Add("tabindex", "-1"); 
       (control as RadNumericTextBox).ButtonUpContainer.Attributes.Add("tabindex", "-1"); 
      } 

      //Recursively call this method if the control in question has children controls and we are told to recurse. 
      if ((Recurse) && (control.HasControls())) 
      { 
       AddOnFocus(control.Controls, saveControl, Recurse); 
      } 
     } 
    } 

    /// <summary> 
    /// Searches the ControlCollection passed in for a match on the ID name string passed in and sets focus on that control if it is found. 
    /// </summary> 
    /// <param name="controls">The collection of controls to search.</param> 
    /// <param name="FocusToID">The ID of the control to set focus on.</param> 
    /// <param name="recurse">Recursively search sub-controls in the passed in control collection?</param>   
    /// <returns>True means keep processing the control list. False means stop processing the control list.</returns> 
    public static bool SetFocus(ControlCollection controls, string FocusToID, bool recurse) 
    { 
     //Return if no control ID to work with. 
     if (string.IsNullOrEmpty(FocusToID) == true) 
     { return false; } 

     //If we get here and don't have controls, return and continue the other controls if applicable. 
     if (controls.Count <= 0) 
     { return true; } 

     foreach (Control control in controls) 
     { 
      //If this is the control we need AND it is Enabled, set focus on it. 
      if (((control is GridTableRow) != true) && //GridTableRow.ClientID throws an error. We don't set focus on a 'Row' anyway. 
       (control.ClientID == FocusToID) && 
       ((control as WebControl).Enabled)) 
      { 
       control.Focus(); 
       //return to caller. If we were recursing then we can stop now. 
       return false; 
      } 
      else 
      { 
       //Otherwise, see if this control has children controls to process, if we are told to recurse. 
       if ((recurse) && (control.HasControls())) 
       { 
        bool _continue = SetFocus(control.Controls, FocusToID, recurse); 
        //If the recursive call sends back false, that means stop. 
        if (_continue != true) 
        { return _continue; } 
       } 
      } 
     } 

     //We are done processing all the controls in the list we were given... 
     // If we get here, then return True to the caller. If this was a recursive call, then 
     // the SetFocus in the call stack above will be told to continue looking since we 
     // didn't find the control in question in the list we were given. 
     return true; 
    } 
0

Yo tenía el mismo problema, decidí mover el código de evento Click para el caso de carga de la página y ejecutarlo en caso de devolución de datos. Y no utilizar un evento de clic en absoluto.

protected void Page_Load(object sender, System.EventArgs e) 
    { 
     if (IsPostBack) 
     { 
      // put code here 
     } 
    } 

en lugar de:

public void ButtonClick(object sender, EventArgs e) 
    { 
     //... 
    } 
1

escriba debajo de código en el evento Page_Load para evitar el doble clic

BtnSaveAndPrint.Attributes.Add("onclick", "return confirm('Are you sure you Want to Save & Print?');") 
Cuestiones relacionadas