views:

288

answers:

2

Hi there,

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 UserControl1 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

+2  A: 

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.

Dug
Thanks Dug, but there is no UpdatePanel in the ASPX page, only in the UserControls - take a look in the code sample.
Neal Hudson
The update panel allows you to do partial page rendering, and will only display changes to the content of the submitting update panel. So when I removed the update panels from the user controls in your code sample and added an update panel surrounding but user controls to the default.aspx page it displayed the text of the label in the second user control as expected.
Dug
As I said in the original post Dug: "If you remove the UpdatePanels out of UserControl1 and UserControl2, the code works." This much I know.The code used to work. I'm looking to find out why it doesn't now, because as far as I can tell there is nothing wrong with the code and should work perfectly as is.
Neal Hudson
The code is working as it should and is rendering all the changes made to the content of the update panel in the first user control. If you want the contents of the second user control to show up it needs to be in the same update panel as the first user control to render.
Dug
I'm sorry Dug, but the code is not working as it should. The first asp:Panel should hide and the second become visible, when the button click event is raised. This is the way the code used to process, irrespective of the updatepanels contained within the UserControls. Nothing changed in the code, but it's stopped working like this.
Neal Hudson
Neal, I've expanded my original answer to provide more details. But basicly only the content of the sending update panel is updated in the browser. Sorry about all the confusion
Dug
Thanks for the article Dug, and I see what you are trying to do. However, in our real world example, these 2 User Controls are used in multiple places so it wouldn't be a straightforward job to put the functionality in usercontrol1 into the aspx page.
Neal Hudson
I wasn't suggesting that you move the functionality. I was trying to show what content gets updated when buttonNext is clicked. You should be able to leave most of the functionality in the user controls. However you need to either add a trigger to the update panel in testusercontrol2 or move the update panel to enclose both usercontrols.
Dug
Dug is completely right here - you can't update the content in one update panel via a trigger from the other update panel, no matter what you try to do.
Charles Boyung
Thanks Dug. I'm still at a loss to explain how this ever worked in the first place, from what you are saying? Has anything changed recently in this area?
Neal Hudson
Charles - I'm not looking to update the content in an update panel. The aspx page containing the 2 usercontrol does not contain any updatepanel. The usercontrol, containing an update panel, raises an event from a button click, this is handled in the aspx page, which hides one regular asp:panel and shows a second one.
Neal Hudson
Neal - There are always changes in this area but update panels have prettt much worked this way since I started working with them. Did your users have Javascript disabled?
Dug
See my answer below - changes have been made between 3.0 and 3.5 with the UpdatePanel, but nothing else that I'm aware of. Also, my answer provides you with an easier way to do what I think you are trying to do.
Charles Boyung
+1  A: 

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.

Charles Boyung
Thanks Charles - I have a question on this though. If the UpdatePanel does not treat the event as a trigger, then why in my code sample when I step through it in debug - the DetailsChanged event is raised and within the Default.aspx.cs the code runs through the testUserControl1_DetailsChanged event hander method?
Neal Hudson