2010-08-26 60 views
0

嗯,我有一個奇怪的問題。DropDownList當異步回發發生時觸發AutoPostback

我有一個頁面上有2個DropDownLists和一個自定義的Web用戶控件。自定義Web用戶控件在其中包含一個UpdatePanel,並且在UpdatePanel中有一個Ajax Timer控件,用於定期更新一系列內容。

當DropDownList中的一個DropDownList並將鼠標懸停在(而不是點擊)某個選項上時,UpdatePanel中的Timer控件異步回發到服務器,DropDownList將「autopostbacks」傳遞給服務器!

我想弄清楚爲什麼異步回發會導致DropDownList的行爲,就像我選擇/點擊一個選項,以便我可以找到解決此問題的方法。

現在很容易重現此問題。 創建一個名爲「TimerUpdatedListing」 Web用戶控制......這是Web用戶控件的代碼ASPX標記:

<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="TimerUpdatedListing.ascx.vb" Inherits="MyNamespace.TimerUpdatedListing" %> 
<div style="width: 150px; height: 150px; overflow: auto; border: solid 1px navy;"> 
    <asp:UpdatePanel ID="anUpdatePanel" runat="server"> 
     <ContentTemplate> 
      <asp:Repeater ID="aRepeater" runat="server"> 
       <ItemTemplate> 
        <div style="border-bottom: solid 1px #EEC900; margin: 3px; padding: 2px;"> 
         Id: 
         <%#Eval("Id")%> 
         <br /> 
         Time: 
         <%#Eval("Time")%> 
        </div> 
       </ItemTemplate> 
      </asp:Repeater> 
      <asp:Timer ID="aTimer" runat="server" Interval="2000"> 
      </asp:Timer> 
     </ContentTemplate> 
    </asp:UpdatePanel> 
</div> 

這是Web用戶控件VB.NET服務器端代碼:

Public Partial Class TimerUpdatedListing 
    Inherits System.Web.UI.UserControl 

    Private _aListOFThings As List(Of Things) 

    Private Sub aTimer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles aTimer.Tick 
     If Session("_aListOfThings") Is Nothing Then 
      _aListOFThings = New List(Of Things) 
     Else 
      _aListOFThings = CType(Session("_aListOfThings"), List(Of Things)) 
     End If 

     If _aListOFThings.Count > 9 Then 
      _aListOFThings = New List(Of Things) 
     End If 

     _aListOFThings.Add(New Things((_aListOFThings.Count + 1).ToString, Now.ToString("hh:mm:ss"))) 
     Session("_aListOfThings") = _aListOFThings 
     aRepeater.DataSource = _aListOFThings 
     aRepeater.DataBind() 
    End Sub 

    Private Class Things 
     Private _time As String 
     Private _id As String 
     Public Property Time() As String 
      Get 
       Return _time 
      End Get 
      Set(ByVal value As String) 
       _time = value 
      End Set 
     End Property 
     Public Property ID() As String 
      Get 
       Return _id 
      End Get 
      Set(ByVal value As String) 
       _id = value 
      End Set 
     End Property 
     Public Sub New(ByVal id As String, ByVal time As String) 
      _id = id 
      _time = time 
     End Sub 
    End Class 
End Class 

現在,在名爲WebForm1.aspx的一個ASPX頁面,加入2個DropDownLists和Web用戶控件:

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="WebForm1.aspx.vb" Inherits="MyNamespace.WebForm1" %> 

<%@ Register Src="TimerUpdatedListing.ascx" TagName="TimerUpdatedListing" TagPrefix="uc1" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title>Test</title> 
</head> 
<body> 
    <form id="form1" runat="server"> 
    <div> 
     <asp:ScriptManager ID="ScriptManager1" runat="server"> 
     </asp:ScriptManager> 
     <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true"> 
      <asp:ListItem Text="1" Value="1" /> 
      <asp:ListItem Text="2" Value="2" /> 
      <asp:ListItem Text="3" Value="3" /> 
      <asp:ListItem Text="4" Value="4" /> 
      <asp:ListItem Text="5" Value="5" /> 
     </asp:DropDownList> 
     <asp:Label ID="selectedValue1" runat="server"></asp:Label> 
     <br /> 
     <asp:DropDownList ID="DropDownList2" runat="server" AutoPostBack="true"> 
      <asp:ListItem Text="a" Value="a" /> 
      <asp:ListItem Text="b" Value="b" /> 
      <asp:ListItem Text="c" Value="c" /> 
      <asp:ListItem Text="d" Value="d" /> 
      <asp:ListItem Text="e" Value="e" /> 
     </asp:DropDownList> 
     <asp:Label ID="selectedValue2" runat="server"></asp:Label> 
     <br /> 
     <br /> 
     <uc1:TimerUpdatedListing ID="TimerUpdatedListing1" runat="server" /> 
    </div> 
    </form> 
</body> 
</html> 

下面是WebForm1.aspx的VB.NET的服務器端代碼頁:

Public Partial Class WebForm1 
    Inherits System.Web.UI.Page 
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
     If String.IsNullOrEmpty(Request.Params("ddl1")) = False Then 
      selectedValue1.Text = Request.Params("ddl1") 
     End If 
     If String.IsNullOrEmpty(Request.Params("ddl2")) = False Then 
      selectedValue2.Text = Request.Params("ddl2") 
     End If 
    End Sub 

    Private Sub DropDownList1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DropDownList1.SelectedIndexChanged 
     Response.Redirect(Request.Url.LocalPath + "?ddl1=" + DropDownList1.SelectedValue.ToString, True) 
    End Sub 

    Private Sub DropDownList2_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DropDownList2.SelectedIndexChanged 
     Response.Redirect(Request.Url.LocalPath + "?ddl2=" + DropDownList2.SelectedValue.ToString, True) 
    End Sub 
End Class 

感謝,

-Frinny

+0

你能發表一些你的代碼嗎? – 2010-08-26 19:08:52

+0

說真的很簡單。我在頁面上有2個DropDownLists。我有一個UpdatePanel的用戶控件...在UpdatePanel中有一個Repeater和一個Timer控件(當計時器滴答時更新的中繼器)... *嘆*用簡單的代碼更新我的原始帖子。 – Frinavale 2010-08-26 19:16:01

+0

您意識到更新面板內的所有內容都會「回傳」給對方嗎?如果你需要單獨控制,我建議使用像[Telerik RadAjaxManager](http://demos.telerik.com/aspnet-ajax/ajax/examples/manager/firstlook/defaultcs.aspx) – 2010-08-26 19:28:29

回答

0

我嘗試了兩種不同的解決方案來解決這個問題。

我做的第一件事是檢查Request.Params(「__ EVENTTARGET」)以查看它是否與DropDownList匹配。如果匹配,那麼我會調用Response.Redirect()方法。

例如:

Public Partial Class WebForm1 
    Inherits System.Web.UI.Page 
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
     If String.IsNullOrEmpty(Request.Params("ddl1")) = False Then 
      selectedValue1.Text = Request.Params("ddl1") 
     End If 
     If String.IsNullOrEmpty(Request.Params("ddl2")) = False Then 
      selectedValue2.Text = Request.Params("ddl2") 
     End If 
    End Sub 

    Private Sub DropDownList1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DropDownList1.SelectedIndexChanged 
     Dim ctrlNameThatCausedPostback As String = Request.Params("__EVENTTARGET") 
     If String.IsNullOrEmpty(ctrlNameThatCausedPostback) = False AndAlso Page.FindControl(ctrlNameThatCausedPostback) Is DropDownList1 Then 
      Response.Redirect(Request.Url.LocalPath + "?ddl1=" + DropDownList1.SelectedValue.ToString, True) 
     End If 
    End Sub 

    Private Sub DropDownList2_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DropDownList2.SelectedIndexChanged 
     Dim ctrlNameThatCausedPostback As String = Request.Params("__EVENTTARGET") 
     If String.IsNullOrEmpty(ctrlNameThatCausedPostback) = False AndAlso Page.FindControl(ctrlNameThatCausedPostback) Is DropDownList2 Then 
      Response.Redirect(Request.Url.LocalPath + "?ddl2=" + DropDownList2.SelectedValue.ToString, True) 
     End If 
    End Sub 
End Class 

我注意到,這並不總是工作。有時候我在DropDownList中選擇了一個選項,並且重定向不會發生,因爲計時器滴答和選定的索引更改事件同時發生。

所以我採取的第二種方法是檢查頁面是否在異步回發到服務器。如果是這樣,那麼我知道這是計時器滴答事件發生,並且重定向不應該發生。

例如:

Public Partial Class WebForm1 
    Inherits System.Web.UI.Page 
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
     If String.IsNullOrEmpty(Request.Params("ddl1")) = False Then 
      selectedValue1.Text = Request.Params("ddl1") 
     End If 
     If String.IsNullOrEmpty(Request.Params("ddl2")) = False Then 
      selectedValue2.Text = Request.Params("ddl2") 
     End If 
    End Sub 

    Private Sub DropDownList1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DropDownList1.SelectedIndexChanged 
     If ScriptManager.GetCurrent(Me.Page).IsInAsyncPostBack = False Then 
      Response.Redirect(Request.Url.LocalPath + "?ddl1=" + DropDownList1.SelectedValue.ToString, True) 
     End If 
    End Sub 

    Private Sub DropDownList2_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DropDownList2.SelectedIndexChanged 
     If ScriptManager.GetCurrent(Me.Page).IsInAsyncPostBack = False Then 
      Response.Redirect(Request.Url.LocalPath + "?ddl2=" + DropDownList2.SelectedValue.ToString, True) 
     End If 
    End Sub 
End Class 

這幫助,並重定向將適當比前一種方法更好發生的可能性;但是,它仍然不是100%。

-Frinny

0

下面是使用觸發器觸發您更新面板的一個例子。把timer.tick事件作爲觸發,並看看會發生什麼

http://www.asp.net/ajax/tutorials/understanding-asp-net-ajax-updatepanel-triggers

PS:我不認爲計時器已被列入更新面板內。實際上,我在代碼隱藏方面構建了我的計時器,並將它們一起排除在標記之外。

+0

感謝您的回覆。 我不需要爲此解決方案使用觸發器。 回覆PS:您可以在UpdatePanel中擁有一個計時器,您只需要注意,無論最後一次請求是否完成,計時器控件都會每隔X毫秒返回服務器。如果計時器控件在最後一個請求返回到瀏覽器之前進行了滴答/回傳,那麼您可能會遇到UpdatePanel「始終在更新」的情況。注意這一點,你會沒事的。 – Frinavale 2010-08-26 21:04:12