单击面板会导致异步回发,但单击子项会导致整页回发
Click on panel causes asynchronous postback but click on children causes full page postback
我有以下 ASCX 控件:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="CalendarDay.ascx.cs"
Inherits="MVP.Calendar.CalendarDay" %>
<asp:Panel ID="DayWrapper" runat="server"
CssClass="day col p-2 border border-left-0 border-top-0 text-truncate">
<div class="date d-flex align-items-center justify-content-center <%= CurrentDayTag %>">
<%= DayText %>
</div>
<div class="row pl-3 pr-3 d-none d-sm-block">
<p class="info"><%= InfoText %></p>
<a class="d-block rounded small align-self-start" title="Test 1"><%= PriceText %></a>
</div>
</asp:Panel>
这是它的部分代码隐藏:
public partial class CalendarDay : UserControl, IPostBackEventHandler
{
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
DayWrapper.CssClass += DayBackgroundTag;
DayWrapper.Attributes["onclick"] = "javascript:__doPostBack('" + UniqueID + "', '')";
}
void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
{
OnDayClicked();
}
}
这是呈现的 DOM:
<div id="MainContent_CalDate_WeekRepeater_DayRepeater_3_CalendarDay_1_DayWrapper_1"
class="day col p-2 border border-left-0 border-top-0 text-truncate day--fully-available"
onclick="javascript:__doPostBack('ctl00$MainContent$CalDate$WeekRepeater$ctl03$DayRepeater$ctl01$CalendarDay', '')">
<div class="date d-flex align-items-center justify-content-center ">17</div>
<div class="row pl-3 pr-3 d-none d-sm-block">
<p class="info"></p>
<a class="d-block rounded small align-self-start" title="Test 1">10€</a>
</div>
</div>
这个 ASCX 控件在一个相当复杂的层次结构中,但最终,所有这些都在 UpdatePanel
.
中
在呈现的 HTML 上,如果我点击 17 或 10€ 文本,我会得到一个完整的页面回发,但如果我点击顶部 div 中的其他任何地方,我接到我的 UpdatePanel
的 AJAX 电话。 这两个 这些调用都正确触发了 RaisePostBackEvent
函数。
我希望并且希望每次都能接到 AJAX 电话。
为什么会发生这种情况,我该如何解决?
您可能需要为异步回发注册控件。尝试改变这个;
DayWrapper.Attributes["onclick"] = "javascript:__doPostBack('" + UniqueID + "', '')";
为此:
DayWrapper.Attributes["onclick"] = Page.ClientScript.GetPostBackEventReference(new PostBackOptions(this));
ScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(this);
这里的主要区别是对 RegisterAsyncPostBackControl
的调用告诉 ScriptManager
该控件确实应该用于异步回发。我也在改变回发 link 的生成方式。这实际上可能不是必需的,但它似乎比手动生成 JavaScript.
更干净
我有以下 ASCX 控件:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="CalendarDay.ascx.cs"
Inherits="MVP.Calendar.CalendarDay" %>
<asp:Panel ID="DayWrapper" runat="server"
CssClass="day col p-2 border border-left-0 border-top-0 text-truncate">
<div class="date d-flex align-items-center justify-content-center <%= CurrentDayTag %>">
<%= DayText %>
</div>
<div class="row pl-3 pr-3 d-none d-sm-block">
<p class="info"><%= InfoText %></p>
<a class="d-block rounded small align-self-start" title="Test 1"><%= PriceText %></a>
</div>
</asp:Panel>
这是它的部分代码隐藏:
public partial class CalendarDay : UserControl, IPostBackEventHandler
{
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
DayWrapper.CssClass += DayBackgroundTag;
DayWrapper.Attributes["onclick"] = "javascript:__doPostBack('" + UniqueID + "', '')";
}
void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
{
OnDayClicked();
}
}
这是呈现的 DOM:
<div id="MainContent_CalDate_WeekRepeater_DayRepeater_3_CalendarDay_1_DayWrapper_1"
class="day col p-2 border border-left-0 border-top-0 text-truncate day--fully-available"
onclick="javascript:__doPostBack('ctl00$MainContent$CalDate$WeekRepeater$ctl03$DayRepeater$ctl01$CalendarDay', '')">
<div class="date d-flex align-items-center justify-content-center ">17</div>
<div class="row pl-3 pr-3 d-none d-sm-block">
<p class="info"></p>
<a class="d-block rounded small align-self-start" title="Test 1">10€</a>
</div>
</div>
这个 ASCX 控件在一个相当复杂的层次结构中,但最终,所有这些都在 UpdatePanel
.
在呈现的 HTML 上,如果我点击 17 或 10€ 文本,我会得到一个完整的页面回发,但如果我点击顶部 div 中的其他任何地方,我接到我的 UpdatePanel
的 AJAX 电话。 这两个 这些调用都正确触发了 RaisePostBackEvent
函数。
我希望并且希望每次都能接到 AJAX 电话。
为什么会发生这种情况,我该如何解决?
您可能需要为异步回发注册控件。尝试改变这个;
DayWrapper.Attributes["onclick"] = "javascript:__doPostBack('" + UniqueID + "', '')";
为此:
DayWrapper.Attributes["onclick"] = Page.ClientScript.GetPostBackEventReference(new PostBackOptions(this));
ScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(this);
这里的主要区别是对 RegisterAsyncPostBackControl
的调用告诉 ScriptManager
该控件确实应该用于异步回发。我也在改变回发 link 的生成方式。这实际上可能不是必需的,但它似乎比手动生成 JavaScript.