开发者

Strange new error with ASP:Panel / UserControl / UpdatePanel combination

I'll try to be as descriptive as possible here. We have some code that was working and now, without being changed, is not. I've isolated the issue, so here is the situation:

We have an ASPX page, and on it there are 2 asp:Panel controls(Panel1 and Panel2). In each of these panels, there is a single WebUserControl (Panel1 contains UserControl1, Panel2 contains UserControl2). There is the AJAX toolkit Scriptmanager on this page, and that is all. When the User first visits the page Panel1 is shown and Panel2 is hidden.

In UserControl1, there is an asp:Panel, a asp:Label containing an asp:UpdatePanel and inside it an asp:Button. In the code behind, there is a delegate and an event to raise it - when you click the button this event is fired. There is a handler for this event in the ASPX page containing the UserControl.

In Panel2 there is an asp:UpdatePanel, asp:Panel and asp:Label

So in the ASPX page, when you click the button in UserControl1, the event is handled. This event handler then hides Panel1 and shows Panel2. At least that is what USED to happen, but this does not happen now.

So to summarise - ASPX page on first visit shows Panel1 with UserControl1. In U开发者_运维技巧serControl1 there is button, User clicks this which raises event in ASPX page, this is supposed to hide Panel1 and show Panel2.

If you remove the UpdatePanels out of UserControl1 and UserControl2, the code works.

Obviously, our 'real life' code here is more complicated - but this small example shows where the problem is.

Here is a zip containing the issue: http://test.wikisaber.es/testajax.zip


Only the content of the update panel will be updated. So you need to remove your update panels from panel1 and panel2 and then place panel1 and panel2 in the same update panel.

Edit: From your sample if we expanded the default.aspx to include TestUserControl1 we get something like:

         <asp:Panel ID="panelUC1" runat="server" Visible="false">
            <asp:Panel ID="panelUC1" runat="server">
              <div>
                <asp:Label ID="Label1" runat="server" Text="User Control 1...." />
              </div>
             <asp:UpdatePanel ID="updatePanel" runat="server" UpdateMode="Conditional">
                 <ContentTemplate>
                    <!-- only the content in from here -->
                    <div>
                      <asp:Button ID="buttonNext" runat="server" OnClick="buttonNext_Click" Text="Click" />
                   </div>  
                    <!-- to here will change when you click on buttonNext -->                       
                </ContentTemplate>
             </asp:UpdatePanel>
           </asp:Panel>
        </asp:Panel>

        <asp:Panel ID="panelUC2" runat="server" Visible="false">
            <tuc2:testUserControl2 ID="testUserControl2" runat="server" />
        </asp:Panel>

When you click on buttonNext the page will postback and go throught the full asp.net lifecycle, however the javascript that controls the update panel will only apply the changes made to contenttemplate of the update panel that made the request to the dom already present in the browser. Try resetting the text of buttonNext in the click event and see what I'm trying to say.

I found this article http://msdn.microsoft.com/en-us/library/Bb398780(en-us,VS.90).aspx on update panels and usercontrols.


Your button is still inside the update panel, and with 3.5, the update panel does always treat events inside it as triggers unless you tell it not to. This most definitely is a change from what was available in 3.0, but it has not changed since 3.5 became available, at least not that I am aware of.

Because of this, what your page was doing is fire the button as part of the partial rendering of the UpdatePanel. Since it was only partially rendering, only the contents inside the UpdatePanel got updated, and the page logic is not inside the UpdatePanel.

To fix this, all you need to do is add this code to your UpdatePanel:

<Triggers>
    <asp:PostBackTrigger ControlID="buttonNext" />
</Triggers>

This will force it to do a post back, and will get your second panel to show up.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜