DropDownList AutoPostback срабатывает при возникновении асинхронной обратной передачи - PullRequest
0 голосов
/ 26 августа 2010

Ну, у меня странная проблема.

У меня есть страница с 2 DropDownLists и пользовательским веб-элементом управления. Пользовательский веб-элемент управления содержит элемент UpdatePanel и элемент управления Ajax Timer в UpdatePanel для периодического обновления списка содержимого.

Когда я «раскрываю» один из списков DropDownList и налагаю (не нажимаю) параметр, в то время как элемент управления Timer в UpdatePanel асинхронно отправляет обратно на сервер, DropDownList «автоматически отсылает» на сервер!

Я пытаюсь выяснить, почему асинхронная обратная передача заставляет DropDownList работать так, как если бы я выбрал / щелкнул опцию, чтобы найти способ обойти эту проблему.

Теперь воспроизвести эту проблему очень просто. Создайте элемент управления веб-пользователя с именем «TimerUpdatedListing» ... это разметка кода 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>

Это код на стороне сервера 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

Теперь на странице ASPX с именем WebForm1.aspx добавьте 2 DropDownLists и пользовательский веб-элемент управления:

<%@ 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>

Вот код VB.NET на стороне сервера для страницы WebForm1.aspx:

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

Ответы [ 2 ]

0 голосов
/ 27 августа 2010

Я попытался два разных решения этой проблемы.

Первым делом я проверил 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 голосов
/ 26 августа 2010

Вот пример использования триггеров для запуска панели обновления. Поместите событие timer.tick в качестве триггера и посмотрите, что произойдет

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

PS: я не думаю, что таймер должен быть включен в панель обновления. Я фактически строю свои таймеры в коде и держу их вне разметки вместе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...