我有一个奇怪的问题。
我有一个包含2个DropDownLists的页面和一个自定义的Web用户控件。自定义Web用户控件中有一个UpdatePanel,UpdatePanel中有一个Ajax Timer控件,用于定期更新内容列表。
当我“下拉”其中一个DropDownLists并将鼠标悬停在(而不是单击)一个选项时,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 :(得分:0)
以下是使用触发器触发更新面板的示例。将timer.tick事件作为触发器,看看会发生什么
http://www.asp.net/ajax/tutorials/understanding-asp-net-ajax-updatepanel-triggers
PS:我不认为计时器必须包含在更新面板中。我实际上是在代码隐藏中构建我的计时器,并将它们全部放在标记之外。
答案 1 :(得分: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