代码之家  ›  专栏  ›  技术社区  ›  Frinavale

当异步回发发生时,DropDownList自动回发将激发

  •  0
  • Frinavale  · 技术社区  · 14 年前

    我有个奇怪的问题。

    我有一个页面,上面有两个下拉列表和一个自定义的Web用户控件。自定义Web用户控件内有一个updatepanel,updatepanel内有一个ajax计时器控件,用于定期更新内容列表。

    当我“下拉”其中一个下拉列表并悬停在某个选项上时(不单击),而updatepanel中的计时器控件异步回发到服务器,下拉列表“自动回发”到服务器!

    我试图弄明白为什么异步回发会导致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个DropDownList和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
    

    谢谢,

    -弗林尼

    2 回复  |  直到 14 年前
        1
  •  0
  •   Chase Florell    14 年前

    下面是一个使用触发器触发更新面板的示例。将timer.tick事件作为触发器,并查看发生的情况

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

    附言:我不认为计时器必须包含在更新面板中。实际上,我在代码隐藏中构建计时器,并将它们放在一起不在标记中。

        2
  •  0
  •   Frinavale    14 年前

    我试图用两种不同的方法来解决这个问题。

    我做的第一件事是检查request.params(“uuEventTarget”)以查看它是否与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%。

    -弗林尼