[BUG]: __doPostback isn't added during a partial postback; this may lead to errors if the method isn't added to the page during initial rendering

The problem can be reproduced as follows: 

1) Create a project. Use the Web Projects Overlay: http://msdn.microsoft.com/asp.net/reference/infrastructure/wap/default.aspx

2) Add a User Defined control (Master)

3) Add two nested User Defined Controls (NCtrl1, NCtrl2). NCtrl1 defaults to visible=true, NCtrl2 defaults to visible=false. Add some text to NCtrl2.

4) In the master control, add a public method to make visible/invisible the nested controls (NCtrl1, NCtrl2). Call it CtrlMeth1.

5) To NCtrl1 Add a GridView nested within an UpdatePanel Atlas mechanism.

6) In the GridView embed a standard Button server control in one of the columns.

7) Attach a public server side onclick event handler to that button.

8) In the Code Behind click event, call CtrlMeth1 to hide NCtrl1 and display NCtrl2. You will note that CtrlMeth1 executes as expected; including the directive to set NCtrl1.visible=false; NCtrl2.visible=true. However NCtrl2 is not displayed. NCtrl1 remains the displayed view.

What appears to be happening here is that ScriptManager is preempting the normal __doPostback for controls embedded within an UpdatePanel. This is not always desirable, as in the above scenario. ScriptManager does provide a method called RegisterAsyncPostbackControl which registers a control outside of a given UpdatePanel to be included within the Atlas Postback simulation. What is really needed here is to extend the functionality of RegisterAsyncPostbackControl to allow a given control to be UN-registered: to be excluded from the Atlas Postback simulation. Armed with this mechanism it should then be possible for the developer to loop through a given control such as the GridView and remove registration for a given control type such as the Button control.

Detailed Code as follows:

Create a new Web Project using the 'Web Projects' overlay. I'm not sure this will be absolutely necessary to reproduce the issue but that is how I have done it. Add a web form and call it MainPage. Then add three Web User Controls called: MainControl, NCtrl1 and NCtrl2. Add code as follows:

MainPage.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="MainPage.aspx.cs" Inherits="PostbackProb.MainPage" %>

<%@ Register TagPrefix="mc" Tagname="MainCtrl" Src="MainControl.ascx" %>

 

<!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>Postback Problem</title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

        <atlas:ScriptManager ID="s1" EnablePartialRendering="true" runat="server" />

        <mc:MainCtrl id="m_ctrlMain" runat="server"></mc:MainCtrl>

    </div>

    </form>

</body>

</html>

 

 MainPage.aspx.cs

namespace PostbackProb

{

    public partial class MainPage : System.Web.UI.Page

    {

        public PostbackProb.MainControl m_ctrlMain;

        protected void Page_Load(object sender, EventArgs e)

        {

 

        }

    }

}

 

MainControl.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MainControl.ascx.cs" Inherits="PostbackProb.MainControl" %>

<%@ Register TagPrefix="mc" Tagname="nctrl1" Src="NCtrl1.ascx" %>

<%@ Register TagPrefix="mc" Tagname="nctrl2" Src="NCtrl2.ascx" %>

 

<div>

    <h1>Main Container Control</h1>

    <br />

    <br />

    <hr />

    <br />

    <mc:nctrl1 id="ctrlN1" Visible="true" runat="server"></mc:nctrl1>

    <mc:nctrl2 id="ctrlN2" Visible="false" runat="server"></mc:nctrl2>

</div>

 

MainControl.ascx.cs

namespace PostbackProb

{

    public partial class MainControl : System.Web.UI.UserControl

    {

        protected void Page_Load(object sender, EventArgs e)

        {

 

        }

 

        public void CtrlMeth1(string InCtrl)

        {

            if (InCtrl == "ctrlN1")

            {

                ctrlN1.Visible = true;

                ctrlN2.Visible = false;

            }

            else

            {

                ctrlN2.Visible = true;

                ctrlN1.Visible = false;

            }

        }

    }

}

 

NCtrl1.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="NCtrl1.ascx.cs" Inherits="PostbackProb.NCtrl1" %>

<div>

    <h1>NCTRL1</h1>

    <asp:Button ID="showGrid" runat="server" Text="Show Grid" OnClick="showGrid_Click" />

    <br />

    <br />

    <atlas:UpdatePanel ID="p1" runat="server">

        <Triggers>

            <atlas:ControlEventTrigger ControlID="showGrid" EventName="Click" />

        </Triggers>

        <ContentTemplate>

            <asp:GridView ID="GridView1" AutoGenerateColumns="false" runat="server" Visible="false" OnRowCommand="GridView1_RowCommand">

                <Columns>

                    <asp:ButtonField ButtonType="Button" DataTextField="RegionID" HeaderText="RegionID" />

                    <asp:BoundField DataField="RegionDescription" HeaderText="RegionDescription" />

                </Columns>

            </asp:GridView>

        </ContentTemplate>

    </atlas:UpdatePanel>

</div>

 

NCtrl1.ascx.cs

namespace PostbackProb

{

    public partial class NCtrl1 : System.Web.UI.UserControl

    {

        protected void Page_Load(object sender, EventArgs e)

        {

        }

 

        protected void showGrid_Click(object sender, EventArgs e)

        {

            SqlConnection Conn = new SqlConnection("workstation id=YourServer;initial catalog=Northwind;User ID=YourID;PWD=YourPassword");

            string strSQL = "select * from Region";

            Conn.Open();

            SqlCommand cmd = new SqlCommand(strSQL, Conn);

            cmd.CommandTimeout = 20;

            SqlDataReader dr = cmd.ExecuteReader();

 

            if (dr.HasRows == true)

            {

                GridView1.Visible = true;

                GridView1.DataSource = dr;

                GridView1.DataBind();

            }

 

            Conn.Close();

            dr.Close();

            cmd.Dispose();

        }

 

        protected void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)

        {

            ((MainPage)this.Page).m_ctrlMain.CtrlMeth1("ctrlN2");

        }

    }

}

 

NCtrl2.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="NCtrl2.ascx.cs" Inherits="PostbackProb.NCtrl2" %>

<div>

    <h1>NCTRL2</h1>

</div>

NCtrl2.ascx.cs

namespace PostbackProb

{

    public partial class NCtrl2 : System.Web.UI.UserControl

    {

        protected void Page_Load(object sender, EventArgs e)

        {

 

        }

    }

}

0
MBrookfield
4/20/2006 1:52:30 PM
asp.net.ajax-discussion 13973 articles. 1 followers. Follow

0 Replies
900 Views

Similar Articles

[PageSpeed] 46

Reply: