2010-07-06 3 views
11

Na stronie mam:Posiada przycisk, aby kliknąć dwukrotnie w ASP.NET (po AutoPostBack tekstowym)

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

W EmailTextBox_Changed, liczy się ile e-maili można znaleźć, przed uruchomieniem wyszukiwania.

Problem polega na tym, że gdy wpisujesz coś w EmailTextBox, i klikniesz przycisk, musisz kliknąć dwa razy, aby uzyskać rzeczywiste wyniki. Dzieje się tak dlatego, że pierwsze kliknięcie wykonuje część "AutoPostBack" z pola tekstowego, a następnie trzeba kliknąć ponownie, aby faktyczny odświeżenie było możliwe.

Bez usuwania "AutoPostBack = true", jak mogę zatrzymać to wymagające dwóch kliknięć w tych okolicznościach?

+0

-Zmiana przycisk z kontrolą serwera do przycisku na bazie klienta, a ponadto użyj JS do tego. – JonH

Odpowiedz

1

Making to sprawdzić po stronie klienta było rozwiązanie tego ... nie wydaje się być sposób, aby temu zapobiec inaczej

1

W rzeczywistości nie trzeba klikać przycisku, aby zdarzenie miało miejsce. Po prostu "wyjdź" z pola tekstowego, to znaczy z "tabbingiem", aby uczynić funkcję AutoPostBack.

Jeśli chcesz zrobić jedno i drugie ogłoszenie, po prostu usuń przycisk i wykonaj czynności w AddButton_Click również w zdarzeniu Textbox_Change.

+0

Hm tak, być może. Chciałem tego uniknąć, ponieważ pole tekstowe tylko liczy się, a przycisk wykonuje pełne pobieranie. – Paul

0

Można tego uniknąć, nie robiąc tego po stronie serwera i przy użyciu Javascript. Nie opublikowałeś też wydarzenia związanego z ładowaniem strony. Czy sprawdzasz, czy to zwrot, czy nie?

Innym sposobem, w jaki można to zrobić, jest zdarzenie, które dzieje się po kliknięciu przycisku, można wywołać z zdarzenia TextChanged i pozbyć się przycisku razem.

+0

Hm tak, rozważałem to. W rzeczywistości jest więcej pól tekstowych, a funkcja autopostback jest dostępna, dzięki czemu możesz zobaczyć liczbę wyników podczas ich filtrowania, a kiedy będziesz gotowy, możesz je wyświetlić. Być może rozwiązaniem jest całkowicie javascript. – Paul

2

szukałem odpowiedzi na ten problem, jak również. W efekcie usunąłem autopostback = true i wykonałem wszystkie czynności z JavaScriptem, tak samo jak ty.

Jednak jedną z rzeczy, z którymi eksperymentowałem przed JavaScriptem, było coś, co utrzymywało kontrolę ostrości po odświeżeniu. Zauważyłem ukryte pole, w którym zapisałem nazwę kontrolki, dla której ostatnie pole DID ma nazwę przycisku wyszukiwania (mój jest przyciskiem zapisu). Tak więc, chociaż nadal nie jestem pewien, jak sprawić, by funkcja "wyszukiwania" uruchamiała "automatycznie", tak jak powinna, co jest zasadniczo związane z łańcuchem zdarzeń odświeżania zarówno z pola tekstowego, jak iz przycisku jeden po drugim, I MOŻNA o tym wiedzieć użytkownik kliknął ten przycisk zapisu, zanim nastąpiło odstąpienie (lub próbowano).

To, co masz na poczcie zwrotnej, to wypalanie zdarzeń w polu tekstowym, a następnie metoda Page_Load lub dowolna metoda cyklu stron, z której możesz skorzystać, aby sprawdzić, na czym skupia się ostatnia kontrolka. Dzięki temu istnieje kilka sposobów na wdrożenie pracy.

Możesz ręcznie dodać kod w każdym zdarzeniu wywoływanym przez funkcję autopostracketingu, np. Pole tekstowe i przycisk wyszukiwania, aby sprawdzić nazwę kontrolki fokusa. Jeśli kontrola, która miała ostatnio fokus NIE jest funkcją autopostraku kontrolnego, którą uruchamiamy, możemy ustawić bool na poziomie strony o nazwie "Run_Controls_Method" na TRUE, w przeciwnym razie ustawimy na false. W ten sposób wiemy, że powinniśmy uruchomić kontrolę, która ma ostatnią metodę ogłaszania zwrotnego.

Na stronie obciążenia, można zrobić coś takiego:

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

The Way I zaimplementować hdfHasFocus jest:

HTML:

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

HTML kod za:

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); 
} 

Kontrola Manager.cs związane Kod:

 /// <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

miałem ten sam problem, postanowiłem przenieść kod zdarzenia kliknięcia na zdarzenie ładowania strony i wykonać go w przypadku odświeżenie strony. I w ogóle nie używać zdarzenia kliknięcia.

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

zamiast:

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

wpisz poniżej kod w zdarzeniu Page_Load aby zapobiec dwukrotnie kliknąć

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