Export (0) Print
Expand All

Using the ASP.NET UpdatePanel Control with Data-Bound Controls

You can create a richer user experience in your AJAX-enabled ASP.NET applications by using partial-page rendering. Partial-page rendering removes the need for the whole page to refresh as the result of a postback. Instead, you can specify only the region of the page to be refreshed. As a result, users no longer see the whole page reload with every postback.

This topic assumes that you are familiar with the UpdatePanel control. If not, review the following topics:

You can enable partial-page rendering by using the UpdatePanel and ScriptManager Web server controls. The UpdatePanel control identifies a region of a page that can be updated. The ScriptManager control keeps track of the UpdatePanel controls that are on a page and the controls that trigger the UpdatePanel controls to refresh. Controls inside an UpdatePanel control that cause a postback are automatically identified as triggers for the update panel. You can also specify controls that are controls outside an UpdatePanel control. External triggers can be child controls of another UpdatePanel control. For more information, see Partial-Page Rendering Overview and UpdatePanel Control Overview.

This topic contains the following:

There is no limit to the number of UpdatePanel controls that you can put on a page. As a result, you can specify regions of a page that are refreshed independently of the whole page and independently of each other.

By default, the UpdateMode property of an UpdatePanel control is set to Always. This means that whenever a partial-page refresh is triggered, the UpdatePanel control refreshes the page, even if the trigger was not for that UpdatePanel control. To make sure that the UpdatePanel control is refreshed only when it has been triggered, you can set the UpdateMode property of the UpdatePanel control to Conditional.

The following example includes two UpdatePanel controls. One control includes Web controls that accept user input, and the other control displays what the user enters. Each UpdatePanel control has its UpdateMode property set to Conditional. As a result, if a user clicks the Cancel button to clear the fields of the input form, only the input form of the UpdatePanel control is refreshed. If a user clicks the Insert button to submit the form, both UpdatePanel controls are refreshed.

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Collections.Generic" %>

<!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>Enter New Employees</title>
    <script runat="server">
        private List<Employee> EmployeeList;

        protected void Page_Load()
        {
            if (!IsPostBack)
            {
                EmployeeList = new List<Employee>();
                EmployeeList.Add(new Employee(1, "Jump", "Dan"));
                EmployeeList.Add(new Employee(2, "Kirwan", "Yvette"));
                ViewState["EmployeeList"] = EmployeeList;
            }
            else
                EmployeeList = (List<Employee>)ViewState["EmployeeList"];

            EmployeesGridView.DataSource = EmployeeList;
            EmployeesGridView.DataBind();
        }

        protected void InsertButton_Click(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(FirstNameTextBox.Text) ||
               String.IsNullOrEmpty(LastNameTextBox.Text)) { return; }

            int employeeID = EmployeeList[EmployeeList.Count-1].EmployeeID + 1;

            string lastName = Server.HtmlEncode(FirstNameTextBox.Text);
            string firstName = Server.HtmlEncode(LastNameTextBox.Text);

            FirstNameTextBox.Text = String.Empty;
            LastNameTextBox.Text = String.Empty;

            EmployeeList.Add(new Employee(employeeID, lastName, firstName));
            ViewState["EmployeeList"] = EmployeeList;

            EmployeesGridView.DataBind();
            EmployeesGridView.PageIndex = EmployeesGridView.PageCount;
        }

        protected void CancelButton_Click(object sender, EventArgs e)
        {
            FirstNameTextBox.Text = String.Empty;
            LastNameTextBox.Text = String.Empty;
        }

        [Serializable]
        public class Employee
        {
            private int _employeeID;
            private string _lastName;
            private string _firstName;

            public int EmployeeID
            {
                get { return _employeeID; }
            }

            public string LastName
            {
                get { return _lastName; }
            }

            public string FirstName
            {
                get { return _firstName; }
            }

            public Employee(int employeeID, string lastName, string firstName)
            {
                _employeeID = employeeID;
                _lastName = lastName;
                _firstName = firstName;
            }
        }

    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        &nbsp;</div>
        <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" />
        <table>
            <tr>
                <td style="height: 206px" valign="top">
                    <asp:UpdatePanel ID="InsertEmployeeUpdatePanel" runat="server" UpdateMode="Conditional">
                        <ContentTemplate>
                          <table cellpadding="2" border="0" style="background-color:#7C6F57">
                            <tr>
                              <td><asp:Label ID="FirstNameLabel" runat="server" AssociatedControlID="FirstNameTextBox" 
                                             Text="First Name" ForeColor="White" /></td>
                              <td><asp:TextBox runat="server" ID="FirstNameTextBox" /></td>
                            </tr>
                            <tr>
                              <td><asp:Label ID="LastNameLabel" runat="server" AssociatedControlID="LastNameTextBox" 
                                             Text="Last Name" ForeColor="White" /></td>
                              <td><asp:TextBox runat="server" ID="LastNameTextBox" /></td>
                            </tr>
                            <tr>
                              <td></td>
                              <td>
                                <asp:LinkButton ID="InsertButton" runat="server" Text="Insert" OnClick="InsertButton_Click" ForeColor="White" />
                                <asp:LinkButton ID="Cancelbutton" runat="server" Text="Cancel" OnClick="CancelButton_Click" ForeColor="White" />
                              </td>
                            </tr>
                          </table>
                          <asp:Label runat="server" ID="InputTimeLabel"><%=DateTime.Now %></asp:Label>
                        </ContentTemplate>
                    </asp:UpdatePanel>
                </td>
                <td style="height: 206px" valign="top">
                    <asp:UpdatePanel ID="EmployeesUpdatePanel" runat="server" UpdateMode="Conditional">
                        <ContentTemplate>
                            <asp:GridView ID="EmployeesGridView" runat="server" BackColor="LightGoldenrodYellow" BorderColor="Tan"
                                BorderWidth="1px" CellPadding="2" ForeColor="Black" GridLines="None" AutoGenerateColumns="False">
                                <FooterStyle BackColor="Tan" />
                                <SelectedRowStyle BackColor="DarkSlateBlue" ForeColor="GhostWhite" />
                                <PagerStyle BackColor="PaleGoldenrod" ForeColor="DarkSlateBlue" HorizontalAlign="Center" />
                                <HeaderStyle BackColor="Tan" Font-Bold="True" />
                                <AlternatingRowStyle BackColor="PaleGoldenrod" />
                                <Columns>
                                    <asp:BoundField DataField="EmployeeID" HeaderText="Employee ID" />
                                    <asp:BoundField DataField="LastName" HeaderText="Last Name" />
                                    <asp:BoundField DataField="FirstName" HeaderText="First Name" />
                                </Columns>
                                <PagerSettings PageButtonCount="5" />
                            </asp:GridView>
                            <asp:Label runat="server" ID="ListTimeLabel"><%=DateTime.Now %></asp:Label>
                        </ContentTemplate>
                        <Triggers>
                            <asp:AsyncPostBackTrigger ControlID="InsertButton" EventName="Click" />
                        </Triggers>
                    </asp:UpdatePanel>
                </td>
            </tr>
        </table>
    </form>
</body>
</html>


You can also nest an UpdatePanel control inside another UpdatePanel control. If you set the UpdateMode property of both the outer and nested controls to Conditional, the outer panel is not refreshed when only the inner panel is triggered. However, if a trigger refreshes the outer panel, both the outer and inner panels are refreshed.

The following example includes a GridView control inside an UpdatePanel control. Each row of the GridView control contains a nested GridView control that is inside a child UpdatePanel control. When a new page of records is requested from an inner GridView control, the page regions of the outer panel and the panels in the other rows of the outer GridView control are not refreshed. When the outer GridView control displays a new page of records, the page regions of the outer panel and of the nested panels are all refreshed.

<%@ Page Language="C#" %>

<!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>Browse Departments</title>
    <script runat="server">
        protected void DepartmentsGridView_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                SqlDataSource s = (SqlDataSource)e.Row.FindControl("EmployeesDataSource");
                System.Data.DataRowView r = (System.Data.DataRowView)e.Row.DataItem;
                s.SelectParameters["DepartmentID"].DefaultValue = r["DepartmentID"].ToString();
            }
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ScriptManager runat="server" ID="ScriptManager1" EnablePartialRendering="true" />
        <asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">
            <ContentTemplate>
        <asp:GridView ID="DepartmentsGridView" runat="server" AllowPaging="True" AllowSorting="True"
            AutoGenerateColumns="False" CellPadding="4" DataSourceID="DepartmentDataSource"
            ForeColor="#333333" GridLines="None" PageSize="3" OnRowDataBound="DepartmentsGridView_RowDataBound">
            <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
            <Columns>
                <asp:BoundField DataField="GroupName" HeaderText="Division" SortExpression="GroupName" >
                    <ItemStyle Width="200px" />
                </asp:BoundField>
                <asp:BoundField DataField="Name" HeaderText="Department Name" SortExpression="Name" >
                    <ItemStyle Width="160px" />
                </asp:BoundField>
                <asp:TemplateField HeaderText="Employees">
                    <ItemTemplate>
                        <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
                            <ContentTemplate>
                                <asp:GridView ID="EmployeesGridView" runat="server" AllowPaging="True" AllowSorting="True"
                                    AutoGenerateColumns="False" BackColor="White" BorderColor="#999999" BorderStyle="None"
                                    BorderWidth="1px" CellPadding="3" DataSourceID="EmployeesDataSource" GridLines="Vertical"
                                    PageSize="4">
                                    <FooterStyle BackColor="#CCCCCC" ForeColor="Black" />
                                    <Columns>
                                        <asp:BoundField DataField="FirstName" HeaderText="First Name" SortExpression="FirstName" >
                                            <ItemStyle Width="80px" />
                                        </asp:BoundField>
                                        <asp:BoundField DataField="LastName" HeaderText="Last Name" SortExpression="LastName" >
                                            <ItemStyle Width="160px" />
                                        </asp:BoundField>
                                    </Columns>
                                    <RowStyle BackColor="#EEEEEE" ForeColor="Black" />
                                    <SelectedRowStyle BackColor="#008A8C" Font-Bold="True" ForeColor="White" />
                                    <PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
                                    <HeaderStyle BackColor="#000084" Font-Bold="True" ForeColor="White" />
                                    <AlternatingRowStyle BackColor="Gainsboro" />
                                </asp:GridView>
                                <asp:Label runat="server" ID="InnerTimeLabel"><%=DateTime.Now %></asp:Label>
                                <asp:SqlDataSource ID="EmployeesDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:AdventureWorksConnectionString %>"
                                    SelectCommand="SELECT HumanResources.EmployeeDepartmentHistory.DepartmentID, 
                                                          HumanResources.vEmployee.EmployeeID, 
                                                          HumanResources.vEmployee.FirstName, 
                                                          HumanResources.vEmployee.LastName 
                                                   FROM HumanResources.EmployeeDepartmentHistory
                                                   INNER JOIN HumanResources.vEmployee 
                                                     ON HumanResources.EmployeeDepartmentHistory.EmployeeID = HumanResources.vEmployee.EmployeeID
                                                   WHERE HumanResources.EmployeeDepartmentHistory.DepartmentID = @DepartmentID
                                                   ORDER BY HumanResources.vEmployee.LastName ASC, HumanResources.vEmployee.FirstName ASC">
                                    <SelectParameters>
                                      <asp:Parameter Name="DepartmentID" DefaultValue="0" Type="int32" />
                                    </SelectParameters>
                                </asp:SqlDataSource>
                            </ContentTemplate>
                        </asp:UpdatePanel>
                    </ItemTemplate>
                    <ItemStyle Height="170px" Width="260px" />
                </asp:TemplateField>
            </Columns>
            <RowStyle BackColor="#F7F6F3" ForeColor="#333333" VerticalAlign="Top" />
            <EditRowStyle BackColor="#999999" />
            <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
            <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
            <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" HorizontalAlign="Left" />
            <AlternatingRowStyle BackColor="White" ForeColor="#284775" VerticalAlign="Top" />
        </asp:GridView>
        <asp:Label runat="server" ID="OuterTimeLabel"><%=DateTime.Now %></asp:Label>
            </ContentTemplate>
        </asp:UpdatePanel>
        &nbsp;
        <asp:SqlDataSource ID="DepartmentDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:AdventureWorksConnectionString %>"
            SelectCommand="SELECT DepartmentID, Name, GroupName FROM HumanResources.Department ORDER BY Name">
        </asp:SqlDataSource>

    </div>
    </form>
</body>
</html>


Controls inside an UpdatePanel control that cause a postback are automatically configured as triggers for that UpdatePanel control. However, you might want to disable the automatic triggers and trigger a refresh of the UpdatePanel control from an external control only. To do this, set the ChildrenAsTriggers property of the UpdatePanel control to false. Then set the UpdateMode property of the UpdatePanel control to Conditional. These property settings will cause a refresh of the panel only if triggered an external control or by a call to the Update method.

The following example displays the categories, subcategories, and names of products from the AdventureWorks sample database. The category list rarely changes and there is no need to refresh the list of categories every time that a list of subcategories or products is displayed. Therefore, in the UpdatePanel control that contains the category list, you can set the ChildrenAsTriggers property to false and the UpdateMode property to Conditional. This makes sure that the UpdatePanel control refreshes only when explicitly requested.

<%@ Page Language="C#" AutoEventWireup="true" %>

<!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>UpdatePanel Example</title>
    <script runat="server">
        protected void ProductsUpdatePanel_Load(object sender, EventArgs e)
        {
            CategoryTimeLabel.Text = DateTime.Now.ToString();
        }

        protected void CategoriesRepeater_ItemCommand(object sender, RepeaterCommandEventArgs e)
        {
            SubcategoriesDataSource.SelectParameters["CategoryID"].DefaultValue = e.CommandArgument.ToString();
            SubcategoriesRepeater.DataBind();
            ProductsDataSource.SelectParameters["SubcategoryID"].DefaultValue = "0";
            ProductsGridView.DataBind();
        }

        protected void SubcategoriesRepeater_ItemCommand(object sender, RepeaterCommandEventArgs e)
        {
            ProductsDataSource.SelectParameters["SubcategoryID"].DefaultValue = e.CommandArgument.ToString();
            ProductsGridView.DataBind();
        }

        protected void RefreshCategoriesButton_Click(object sender, EventArgs e)
        {
            SubcategoriesDataSource.SelectParameters["CategoryID"].DefaultValue = "0";
            SubcategoriesRepeater.DataBind();
            ProductsDataSource.SelectParameters["SubcategoryID"].DefaultValue = "0";
            ProductsGridView.DataBind();
        }
</script>
</head>
<body>
  <form id="form1" runat="server">
  <div>
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <table>
      <tr>
        <td valign="top" style="width:120px">
          <asp:UpdatePanel ID="ProductsUpdatePanel" runat="server" 
                           ChildrenAsTriggers="False" 
                           OnLoad="ProductsUpdatePanel_Load" UpdateMode="Conditional">
            <ContentTemplate>
              <asp:Repeater ID="CategoryRepeater" runat="server" DataSourceID="CategoriesDataSource"
                            OnItemCommand="CategoriesRepeater_ItemCommand">
                <ItemTemplate>
                  <asp:LinkButton runat="server" ID="SelectCategoryButton" 
                                  Text='<%# Eval("Name") %>'
                                  CommandName="SelectCategory"
                                  CommandArgument='<%#Eval("ProductCategoryID") %>' /><br />
                </ItemTemplate>
              </asp:Repeater>
              <asp:SqlDataSource ID="CategoriesDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:AdventureWorksConnectionString %>"
                  SelectCommand="SELECT Name, ProductCategoryID FROM Production.ProductCategory ORDER BY ProductCategoryID">
              </asp:SqlDataSource>
              <br />
              <asp:Label ID="CategoryTimeLabel" runat="server" Text="Label" Font-Size="Smaller"></asp:Label>
            </ContentTemplate>
            <Triggers>
              <asp:AsyncPostBackTrigger ControlID="RefreshCategoriesButton" EventName="Click" />
            </Triggers>
          </asp:UpdatePanel>
          <asp:LinkButton runat="Server" ID="RefreshCategoriesButton" Text="Refresh Category List"
                          OnClick="RefreshCategoriesButton_Click" Font-Size="smaller" />
        </td>
        <td valign="top">
          <asp:UpdatePanel ID="SubcategoriesUpdatePanel" runat="server">
            <ContentTemplate>
              <asp:Repeater ID="SubcategoriesRepeater" runat="server" DataSourceID="SubcategoriesDataSource"
                            OnItemCommand="SubcategoriesRepeater_ItemCommand" >
                <ItemTemplate>
                  <asp:LinkButton runat="server" ID="SelectSubcategoryButton" 
                                  Text='<%# Eval("Name") %>'
                                  CommandName="SelectSubcategory"
                                  CommandArgument='<%#Eval("ProductSubcategoryID") %>' /><br />
                </ItemTemplate>
              </asp:Repeater>
              <asp:SqlDataSource ID="SubcategoriesDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:AdventureWorksConnectionString %>"
                  SelectCommand="SELECT Name, ProductSubcategoryID FROM Production.ProductSubcategory 
                                 WHERE Production.ProductSubcategory.ProductCategoryID = @CategoryID 
                                 ORDER BY Name">
                 <SelectParameters>
                   <asp:Parameter Name="CategoryID" DefaultValue="0" />
                 </SelectParameters>
              </asp:SqlDataSource>
            </ContentTemplate>
          </asp:UpdatePanel>
        </td>
        <td valign="top">
          <asp:UpdatePanel ID="ProductUpdatePanel" runat="server">
            <ContentTemplate>
              <asp:GridView ID="ProductsGridView" runat="server" AllowPaging="True" AutoGenerateColumns="False" BackColor="White" BorderColor="#E7E7FF" BorderStyle="None" BorderWidth="1px" CellPadding="3" DataKeyNames="ProductID" DataSourceID="ProductsDataSource" GridLines="Horizontal">
                <FooterStyle BackColor="#B5C7DE" ForeColor="#4A3C8C" />
                <Columns>
                  <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" >
                    <ItemStyle Width="240px" />
                  </asp:BoundField>
                </Columns>
                <RowStyle BackColor="#E7E7FF" ForeColor="#4A3C8C" />
                <SelectedRowStyle BackColor="#738A9C" Font-Bold="True" ForeColor="#F7F7F7" />
                <PagerStyle BackColor="#E7E7FF" ForeColor="#4A3C8C" HorizontalAlign="Right" />
                <HeaderStyle BackColor="#4A3C8C" Font-Bold="True" ForeColor="#F7F7F7" />
                <AlternatingRowStyle BackColor="#F7F7F7" />
              </asp:GridView>
              <asp:SqlDataSource ID="ProductsDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:AdventureWorksConnectionString %>"
                  SelectCommand="SELECT ProductID, Name, ProductSubcategoryID FROM Production.Product WHERE (ProductSubcategoryID = @SubcategoryID) ORDER BY Name">
                <SelectParameters>
                  <asp:Parameter DefaultValue="0" Name="SubcategoryID" />
                </SelectParameters>
              </asp:SqlDataSource>
            </ContentTemplate>
          </asp:UpdatePanel>
        </td>
      </tr>
    </table>
  </div>
  </form>
</body>
</html>


Controls that trigger an UpdatePanel control refresh must be registered with the ScriptManager control on the page. This occurs automatically for the child controls in an UpdatePanel control. You can specify triggers declaratively using the Triggers collection of an UpdatePanel control. Additionally, you can programmatically identify triggers and use server code to cause an UpdatePanel control to refresh.

In cases where a trigger control is not available at design time, you can register the control as a trigger by using the RegisterAsyncPostBackControl method of the ScriptManager control. Controls that are programmatically identified as triggers must be registered every time that a postback occurs. We recommend that you put calls to the RegisterAsyncPostBackControl method in the Page_Load event for your page, as shown in the following example:

protected void Page_Load()
{
    ScriptManager1.RegisterAsyncPostBackControl(SurveyDataList);
}


To programmatically refresh the UpdatePanel control, you can call the Update method of an UpdatePanel control. This is useful if you must perform some processing on the server before refreshing the UpdatePanel control. The following example shows how to refresh an UpdatePanel programmatically.

protected void ChoicesRadioButtonList_SelectedIndexChanged(object sender, EventArgs e)
{
    SortedList answers = this.AnsweredQuestions;
    RadioButtonList r = (RadioButtonList)sender;
    answers[r.ToolTip] = r.SelectedValue;
    this.AnsweredQuestions = answers;

    ResultsList.DataSource = this.AnsweredQuestions;
    ResultsList.DataBind();

    if (this.AnsweredQuestions.Count == SurveyDataList.Items.Count)
        SubmitButton.Visible = true;

    UpdatePanel1.Update();
}


The following example shows a page that registers a control as a trigger by using the RegisterAsyncPostBackControl method. It then programmatically refreshes an UpdatePanel control by using the Update method.

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

    protected SortedList AnsweredQuestions
    {
        get { return (SortedList)(ViewState["AnsweredQuestions"] ?? new SortedList()); }
        set { ViewState["AnsweredQuestions"] = value; }
    }

    protected void Page_Load()
    {
        ScriptManager1.RegisterAsyncPostBackControl(SurveyDataList);
    }

    protected void ChoicesRadioButtonList_SelectedIndexChanged(object sender, EventArgs e)
    {
        SortedList answers = this.AnsweredQuestions;
        RadioButtonList r = (RadioButtonList)sender;
        answers[r.ToolTip] = r.SelectedValue;
        this.AnsweredQuestions = answers;

        ResultsList.DataSource = this.AnsweredQuestions;
        ResultsList.DataBind();

        if (this.AnsweredQuestions.Count == SurveyDataList.Items.Count)
            SubmitButton.Visible = true;

        UpdatePanel1.Update();
    }

    protected void SubmitButton_Click(object sender, EventArgs e)
    {
        // Submit responses.
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>Registering Controls as Async Postback Controls</title>
    <style type="text/css">
    .AnswerFloatPanelStyle {
    background-color: bisque;
    position: absolute;
    right: 10px;
    height: 130px;
    width: 150px;
    border-right: silver thin solid; border-top: silver thin solid; 
    border-left: silver thin solid; border-bottom: silver thin solid;    
    }
    </style>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:ScriptManager ID="ScriptManager1" runat="server" />
            <div id="AnswerFloatPanel" class="AnswerFloatPanelStyle" runat="server">
                <asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
                    <ContentTemplate>
                        Completed Questions:
                        <asp:DataList ID="ResultsList" runat="server">
                            <ItemTemplate>
                                <asp:Label ID="ResultQuestion" runat="server" Text='<%# Eval("Key") %>' />
                                ::
                                <asp:Label ID="ResultAnswer" runat="server" Text='<%# Eval("Value") %>' />
                            </ItemTemplate>
                        </asp:DataList>
                        <p style="text-align: right">
                            <asp:Button ID="SubmitButton" Text="Submit" runat="server" Visible="false"
                                OnClick="SubmitButton_Click" />
                        </p>
                        <asp:Label ID="Message" runat="Server" />
                    </ContentTemplate>
                </asp:UpdatePanel>
            </div>

            <asp:XmlDataSource ID="SurveyDataSource" 
                               runat="server" 
                               XPath="/Questions/Question"
                               DataFile="~/App_Data/SurveyQuestions.xml"/>
            <asp:DataList
                ID="SurveyDataList"
                DataSourceID="SurveyDataSource"
                runat="server">

                <ItemTemplate>
                  <table cellpadding="2" cellspacing="2">
                    <tr>
                      <td valign="top">
                        <asp:Label id="QuestionLabel" Text='<%# XPath("@Title")%>' runat="server" />
                      </td>
                    </tr>
                    <tr><td>
                      <asp:RadioButtonList ID="ChoicesRadioButtonList" runat="server" 
                        DataSource='<%#XPathSelect("Choices/Choice") %>'
                        DataTextField="InnerText" DataValueField="InnerText" 
                        AutoPostBack="True"
                        ToolTip='<%# "Question" + XPath("@ID") %>'
                        OnSelectedIndexChanged="ChoicesRadioButtonList_SelectedIndexChanged"/>
                    </td></tr>
                  </table>
                  <hr />
                </ItemTemplate>
            </asp:DataList>
        </div>
    </form>
</body>
</html>


You can add an UpdatePanel to a user control or to a custom control. However, the page that contains your control might not include the necessary ScriptManager control with its EnablePartialRendering property set to true. Therefore, in your custom control you can determine whether partial-page rendering is enabled by calling the static GetCurrent method of the ScriptManager control. If there is no ScriptManager control on the page, the GetCurrent method returns null. Otherwise, you can check the value of the EnablePartialRendering property of the ScriptManager control and include an UpdatePanel control if the EnablePartialRendering property returns true.

The following example shows the CreateChildControls method of a custom control that inherits from the CompositeControl class. If partial-page rendering is enabled for the page, the custom control puts its contents in an UpdatePanel control.

protected override void CreateChildControls() {
    base.CreateChildControls();

    Control parent;
    Control container;

    // Get a reference to the ScriptManager object for the page
    // if one exists.
    ScriptManager sm = ScriptManager.GetCurrent(Page);

    if (sm == null || !sm.EnablePartialRendering)
    {
        // If partial rendering is not enabled, set the parent
        // and container as a basic control. 
        container = new Control();
        parent = container;
    }
    else
    {
        // If partial rendering is enabled, set the parent as
        // a new UpdatePanel object and the container to the 
        // content template of the UpdatePanel object.
        UpdatePanel up = new UpdatePanel();
        container = up.ContentTemplateContainer;
        parent = up;
    }

    AddDataboundControls(container);

    Controls.Add(parent);
}


The following example shows a custom control that includes an UpdatePanel control if partial-page rendering is enabled.

<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Register Namespace="UpdatePanelTutorialCustom.CS" TagPrefix="sample" %>

<!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>Browse Products</title>
    <script runat="server">
        protected void ProductsView1_RowCommand(object sender, EventArgs e)
        {
            ShoppingCartList.DataSource = ProductsView1.Cart;
            ShoppingCartList.DataBind();
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ScriptManager runat="server" ID="ScriptManager1" EnablePartialRendering="false" />
        <h2>Browse Products</h2>
        <sample:ProductsView runat="server" ID="ProductsView1" PageSize="5" OnRowCommand="ProductsView1_RowCommand" />

        <asp:UpdatePanel runat="server" ID="CartUpdatePanel">
          <ContentTemplate>
            <h3>Selected Items</h3>
            <asp:BulletedList BulletStyle="numbered" runat="server" ID="ShoppingCartList" />
          </ContentTemplate>
        </asp:UpdatePanel>
     </div>
    </form>
</body>
</html>


using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Web.UI;
using System.Drawing;

namespace UpdatePanelTutorialCustom.CS
{
    public class ProductsView : CompositeControl
    {
        private int _pageSize;
        private ArrayList _cart;
        private static readonly object EventRowCommand = new object();

        public int PageSize
        {
            get { return _pageSize; }
            set { _pageSize = value; }
        }

        public ArrayList Cart
        {
            get { return _cart; }
        }

        protected override void CreateChildControls() {
            base.CreateChildControls();

            Control parent;
            Control container;

            // Get a reference to the ScriptManager object for the page
            // if one exists.
            ScriptManager sm = ScriptManager.GetCurrent(Page);

            if (sm == null || !sm.EnablePartialRendering)
            {
                // If partial rendering is not enabled, set the parent
                // and container as a basic control. 
                container = new Control();
                parent = container;
            }
            else
            {
                // If partial rendering is enabled, set the parent as
                // a new UpdatePanel object and the container to the 
                // content template of the UpdatePanel object.
                UpdatePanel up = new UpdatePanel();
                container = up.ContentTemplateContainer;
                parent = up;
            }

            AddDataboundControls(container);

            Controls.Add(parent);
        }

        private void GridView_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            string productID;

            if (e.CommandName == "AddToCart")
            {
                productID = ((GridView)sender).DataKeys[Convert.ToInt32(e.CommandArgument)].Value.ToString();
                if (_cart == null) { GetCart(); }
                if (_cart.IndexOf(productID) == -1)
                    _cart.Add(productID);
                ViewState["Cart"] = _cart;
            }

            if (e.CommandName == "RemoveFromCart")
            {
                productID = ((GridView)sender).DataKeys[Convert.ToInt32(e.CommandArgument)].Value.ToString();
                if (_cart == null) { GetCart(); }
                _cart.Remove(productID);
                ViewState["Cart"] = _cart;
            }

            this.OnRowCommand(new EventArgs());
        }

        private void GetCart()
        {
            if (ViewState["Cart"] == null)
                _cart = new ArrayList();
            else
                _cart = (ArrayList)ViewState["Cart"];
        }

        public event EventHandler RowCommand
        {
            add { Events.AddHandler(EventRowCommand, value); }
            remove { Events.RemoveHandler(EventRowCommand, value); }
        }

        protected virtual void OnRowCommand(EventArgs e)
        {
            EventHandler handler = (EventHandler)Events[EventRowCommand];
            if (handler != null)
            {
                handler(this, e);
            }
        }

        private void AddDataboundControls(Control parent)
        {
            SqlDataSource ds = new SqlDataSource();
            ds.ID = "ProductsSqlDataSource";
            ds.ConnectionString = 
              ConfigurationManager.ConnectionStrings["AdventureWorksConnectionString"].ConnectionString;
            ds.SelectCommand =
              "SELECT Production.ProductDescription.Description, Production.Product.Name, Production.ProductPhoto.ThumbnailPhotoFileName, " +
              "Production.Product.ProductID " +
              "FROM Production.Product INNER JOIN " +
              "Production.ProductProductPhoto ON Production.Product.ProductID = Production.ProductProductPhoto.ProductID INNER JOIN " +
              "Production.ProductPhoto ON Production.ProductProductPhoto.ProductPhotoID = Production.ProductPhoto.ProductPhotoID INNER JOIN " +
              "Production.ProductModelProductDescriptionCulture ON  " +
              "Production.Product.ProductModelID = Production.ProductModelProductDescriptionCulture.ProductModelID INNER JOIN " +
              "Production.ProductDescription ON  " +
              "Production.ProductModelProductDescriptionCulture.ProductDescriptionID = Production.ProductDescription.ProductDescriptionID";

            GridView gv = new GridView();
            gv.ID = "ProductsGridView";
            gv.DataSourceID = ds.ID;
            gv.AutoGenerateColumns = false;
            gv.DataKeyNames = new string[] { "ProductID" };
            gv.GridLines = GridLines.None;
            gv.HeaderStyle.BackColor = Color.LightGray;
            gv.AlternatingRowStyle.BackColor = Color.LightBlue;
            gv.AllowPaging = true;
            gv.PageSize = _pageSize;
            gv.RowCommand += this.GridView_RowCommand;

            ImageField if1 = new ImageField();
            if1.HeaderText = "Product";
            if1.DataImageUrlField = "ThumbnailPhotoFileName";
            if1.DataImageUrlFormatString = @"..\images\thumbnails\{0}";

            BoundField bf1 = new BoundField();
            bf1.HeaderText = "Name";
            bf1.DataField = "Name";

            BoundField bf2 = new BoundField();
            bf2.HeaderText = "Description";
            bf2.DataField = "Description";

            ButtonField btf1 = new ButtonField();
            btf1.Text = "Add";
            btf1.CommandName = "AddToCart";

            ButtonField btf2 = new ButtonField();
            btf2.Text = "Remove";
            btf2.CommandName = "RemoveFromCart";

            gv.Columns.Add(if1);
            gv.Columns.Add(bf1);
            gv.Columns.Add(bf2);
            gv.Columns.Add(btf1);
            gv.Columns.Add(btf2);

            parent.Controls.Add(new LiteralControl("<br />"));
            parent.Controls.Add(gv);
            parent.Controls.Add(new LiteralControl("<br />"));
            parent.Controls.Add(ds);
        }
    }
}


Community Additions

ADD
Show:
© 2014 Microsoft