2010-07-06 62 views
11

Trên một trang tôi có:Có nút bấm hai lần trong asp.net (sau AutoPostBack textbox)

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

Trong EmailTextBox_Changed, nó đếm lên bao nhiêu email có thể được tìm thấy, trước khi chạy tìm kiếm.

Vấn đề là, khi bạn nhập nội dung nào đó vào EmailTextBox và nhấp vào nút, bạn phải nhấp hai lần để nhận kết quả thực tế. Điều này là do nhấp chuột đầu tiên đang thực hiện phần "AutoPostBack" từ hộp văn bản và sau đó bạn phải nhấp lại để thực hiện đăng lại nhấp chuột thực tế.

Không xóa "AutoPostBack = true", làm cách nào tôi có thể dừng yêu cầu nhấp chuột trong các trường hợp này?

+0

-Thay đổi nút từ một điều khiển máy chủ để một nút client dựa, ngoài ra, sử dụng JS cho việc này. – JonH

Trả lời

1

Làm cho nó một tấm séc phía khách hàng là giải pháp này ... có vẻ không phải là một cách để ngăn chặn nó bằng cách khác

1

Thực tế, bạn không phải nhấp vào nút để thực hiện sự kiện đầu tiên. Chỉ cần 'rời' hộp văn bản, tức là với 'tabbing' ra khỏi nó để làm cho AutoPostBack xảy ra.

Nếu bạn muốn thực hiện cả hai trong một lần đăng lại, chỉ cần xóa nút và thực hiện những việc bạn làm trong AddButton_Click cũng trong sự kiện Textbox_Change.

+0

Hm vâng, có lẽ. Tôi muốn thử và tránh điều đó vì hộp văn bản chỉ thực hiện đếm và nút tìm nạp đầy đủ. – Paul

0

Bạn có thể tránh điều này bằng cách không thực hiện phía máy chủ và sử dụng Javascript. Bạn cũng không đăng sự kiện tải trang của mình. Bạn đang kiểm tra xem nó có đăng lại hay không?

Một cách khác bạn có thể thực hiện việc này là sự kiện xảy ra khi nhấp vào nút có thể được gọi từ sự kiện TextChanged và loại bỏ tất cả các nút cùng nhau.

+0

Hm yeah, tôi đã xem xét điều này. Trên thực tế có nhiều hộp văn bản hơn và tính năng tự động phát lại ở trên đó để bạn có thể thấy số lượng kết quả khi lọc chúng và khi bạn đã sẵn sàng, bạn có thể hiển thị chúng. Có lẽ một giải pháp hoàn toàn javascript là con đường phía trước. – Paul

2

tôi đang tìm kiếm một câu trả lời cho vấn đề này là tốt. Tôi đã kết thúc việc xóa tất cả autopostback = true và thực hiện tất cả các hành động với JavaScript, giống như bạn.

Tuy nhiên, một trong những điều tôi đã thử nghiệm trước khi JavaScript là điều gì đó để duy trì tiêu điểm kiểm soát sau khi đăng lại. Tôi nhận thấy trường ẩn mà tôi sử dụng để lưu trữ tên của điều khiển có tiêu điểm cuối cùng DID có tên nút tìm kiếm (tôi là nút lưu). Vì vậy, trong khi tôi vẫn không chắc chắn làm thế nào để có được chức năng 'tìm kiếm' để bắn 'tự động' như nó cần, đó là cơ bản để chuỗi các sự kiện postback từ cả hai hộp văn bản và nút với nhau cái khác, tôi có thể biết rằng người dùng đã nhấp vào nút lưu đó trước khi đăng lại xảy ra (hoặc cố gắng).

Vì vậy, những gì bạn có trên postback là sự kiện hộp văn bản của bạn bắn, và sau đó phương pháp Page_Load, hoặc bất kỳ phương pháp chu kỳ trang bạn muốn sử dụng, nơi bạn có thể kiểm tra để xem điều khiển cuối cùng để có tập trung được. Với điều này, có một số cách bạn có thể thực hiện một công việc xung quanh.

Tắt tay, bạn có thể thêm mã vào mọi sự kiện phát sinh từ điều khiển tự động kiểm soát, như hộp văn bản và nút tìm kiếm, để kiểm tra tên của điều khiển lấy nét. Nếu điều khiển đã tập trung cuối cùng không phải là chức năng tự động khởi động lại của điều khiển mà chúng ta đang chạy, chúng ta có thể thiết lập một bool cấp trang gọi là 'Run_Controls_Method' thành TRUE, khác, đặt nó thành false. Bằng cách này, chúng ta biết chúng ta nên chạy điều khiển có phương thức postback tập trung cuối cùng.

Ngày tải trang, bạn có thể làm một cái gì đó như:

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

Con đường tôi thực hiện hdfHasFocus là:

HTML:

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

HTML code sau:

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

Kiểm soát Mã liên quan đến Manager.cs:

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

Tôi đã gặp sự cố tương tự, tôi đã quyết định chuyển mã sự kiện nhấp chuột vào sự kiện tải trang và thực thi nó trong trường hợp đăng lại. Và không sử dụng sự kiện nhấp chuột nào cả.

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

thay vì:

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

Viết dưới mã trong sự kiện Page_Load để ngăn chặn hai lần nhấp

BtnSaveAndPrint.Attributes.Add("onclick", "return confirm('Are you sure you Want to Save & Print?');") 
Các vấn đề liên quan