我的印象是,嵌套的UpdatePanel中的控件将导致顶层UpdatePanel刷新(从而刷新两个UpdatePanel),因为该控件上的任何事件都充当“隐式”触发器。这是对的吗?
我一直试图连接这样的东西 -
UserControl
Parent UpdatePanel
"Show" button
ASP:Panel
Dynamically added UserControls, each with UpdatePanels
单击“显示”按钮时,ASP:Panel变为可见,并开始根据某些后端逻辑动态地将UserControls添加到自身。
每个动态添加的控件(以下称为UserControls)都有自己的Atlas启用按钮和链接,因此它们也有UpdatePanels。目前,当我单击其中一个UserControls中的链接时,ASP:Panel的所有内容都会消失,就好像它正在重新渲染一样。我的所有动态添加的控件都会消失,并且调试器中没有捕获任何单击事件。
我假设这里发生的事情是驻留在嵌套更新面板中的控件导致父UpdatePanel回发,因为它们触发了“隐式”触发器。有没有办法让我的UserControls自动运行而不是弄乱ASP:包含它们的面板?
如果没有,我应该采取什么策略?如果我必须在其中一个(可能很多)UserControls上发生事件时重新渲染整个ASP:Panel,这意味着我将不得不重新创建UserControls,这需要花费一些精力来创建。我还必须保留某种视图状态来重新创建它们。我对ASP.NET有点新鲜,听起来令人生畏。我宁愿永远不要刷新最高级别的UserControl和ASP:Panel,如果我可以避免它,并让每个动态添加的UserControls以异步方式触发和处理自己的事件。
编辑:我没有动态添加控件,而是将它们添加到标记中(这不是一个糟糕的解决方案)。因此摆脱了控件消失的问题,因为现在控件不是动态添加的,而是存在于标记中。但是,仍然会显示父UpdatePanel帖子,因为所有UserControl都会被发布而不是一个。如何只进行一次UserControl回发?另外,我想知道如果动态添加控制消失的问题怎么办?
答案 0 :(得分:16)
首先,请记住:UpdatePanels 不会改变页面的生命周期。
所有控制树(包括UpdatePanels)必须重建,就像正常回发生命周期一样。 1 2 UpdatePanel确保仅返回呈现的(HTML)视图的部分。删除所有UpdatePanel 应该导致相同的行为,除了完整的回发。例如,只有表示嵌套UpdatePanel的HTML(可能是因为数据已更改)可能会在XHR响应中发回。
要获得“真实”的AJAX,请考虑页面方法。或者,DevExpress(也许是Telerik和其他人?)提供了他们自己的“回调面板”形式,它类似于UpdatePanels,但可以绕过部分生命周期(因此通常不会完全支持ViewState模型)或者可能会引入他们自己的怪癖。)
虽然不理解上述内容是控制“消失”的最可能原因,但这是我的规则:不要让[嵌套] UpdatePanels“自动”工作。
将遇到具有动态控件和嵌套UpdatePanels 的边缘情况。可能有一种很好的方法可以解决这个问题,但我在多次尝试中失败了。
相反,对于每个更新面板,请运行:
UpdateMode="Conditional"
ChildrenAsTriggers="False"
使用“条件”UpdateMode,请确保手动指定触发控件或根据需要调用panel.Update()
(尽管这会强制连接控件)。根据需要,ChildrenAsTriggers="True"
也可能有效。最重要的是UpdateMode 不是“Always”,这是默认值。
切换到这种方法后,我没有问题 - 好吧,几乎没有 - 使用嵌套的UpdatePanels。
快乐的编码!
1 如果在禁用部分渲染(在ScriptManager中)的页面无法正确渲染(例如,所有请求都是完整的回发),则没有理由期望/相信它会正常工作使用UpdatePanels。
2 有时需要在控制树中“欺骗”昂贵的重新计算以获得不会重新渲染的控件。但是,我会考虑这些高级案例,只有在性能分析表明存在特定需求时才应该这样做。
答案 1 :(得分:1)
我有一个类似的问题,一个重量级的ajax Gridview
控件,一个HTML页面有多个UpdatePanels
,有些嵌套,有些没有。
我花了3个多星期的试错,阅读,测试,调试和原型设计才能最终解决所有回发和部分回发问题。
但是我确实注意到了一种对我有用的模式。
与@user上面的响应类似,请确保您的UpdatePanel设置为条件,并且仅在您希望页面执行完整回发的最终或决定性控件上设置asp:PostBackTrigger
。我总是尽可能使用asp:AsyncPostBackTrigger
。
例如,如果您在GridView中使用UpdatePanel并且想要在gridview的行的单元格内弹出一个窗口,那么您需要使用嵌套的UpdatePanel。
即
<asp:TemplateField HeaderText="Actions & Communications">
<ItemTemplate>
<asp:UpdatePanel ID="upAction1" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnActionOK" />
</Triggers>
<ContentTemplate>
...
...
<ajaxToolkit:ModalPopupExtender ID="ajaxMPE" runat="server"
BackgroundCssClass="modalBackground"
PopupControlID="upAction2"
TargetControlID="btnADDaction">
</ajaxToolkit:ModalPopupExtender>
<asp:UpdatePanel ID="upAction2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Panel ID="pnlACTION" runat="server" CssClass="pnlACTION">
<div id="divHDR">
<asp:Label ID="lblActionHdr" runat="server">** header **</asp:Label>
</div>
<div id="divBOD">
<table style="width: 98%; text-align:left">
<tr>
<td colspan="2">
Please enter action item:<br />
<asp:TextBox ID="txtAction" runat="server" ValidationGroup="vgAction" TextMode="MultiLine" Rows="3" Width="98%"></asp:TextBox>
<asp:RequiredFieldValidator ID="rfvAction" runat="server" ControlToValidate="txtAction" ValidationGroup="vgAction"
ErrorMessage="* Required" SetFocusOnError="True"></asp:RequiredFieldValidator></td>
</tr>
<tr>
<td colspan="2">
Select staff assigned to this task:<br />
<asp:DropDownList ID="ddlActionStaff" runat="server" AppendDataBoundItems="true" ValidationGroup="vgAction" />
<asp:RequiredFieldValidator ID="rfvStaff" runat="server" ControlToValidate="ddlActionStaff" InitialValue="0" ValidationGroup="vgAction"
ErrorMessage="* Required" SetFocusOnError="True" Width="98%"></asp:RequiredFieldValidator></td>
</tr>
<tr>
<td colspan="2" style="text-align: center">
<asp:Button ID="btnActionOK" runat="server" Text="OK" OnClick="btnActionOK_Click" ValidationGroup="vgAction" CausesValidation="false" />
<asp:Button ID="btnActionCANCEL" runat="server" Text="CANCEL" OnClick="btnActionCANCEL_Click" ValidationGroup="vgAction" CausesValidation="false" />
</td>
</tr>
</table>
</div>
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
</td>
</tr>
</table>
<asp:SqlDataSource ID="sdsTETactions" runat="server" ConnectionString="<%$ ConnectionStrings:ATCNTV1ConnectionString %>"
...
...
</asp:SqlDataSource>
</ContentTemplate>
</asp:UpdatePanel>
</ItemTemplate>
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
请注意以下几点:
有一篇很棒的文章here,可以更好地解释它。
我希望这有助于某人