Использование элемента управления UpdatePanel ASP.NET с элементами управления с привязкой к данным

Visual Studio 2010

Обновлен: Ноябрь 2007

В приложениях ASP.NET с технологией AJAX можно реализовать более широкие возможности взаимодействия в пользователем с помощью частичной отрисовки страницы. Частичная отрисовка страницы избавляет от необходимости обновления всей страницы в результате обратной передачи. Вместо этого можно указать только область страницы, которая будет обновлена. В результате пользователи больше не будут видеть повторную загрузку всей страницы после каждой обратной передачи.

Для выполнения задания в этом разделе необходимо общее преставление об элементе управления UpdatePanel. Ознакомьтесь со следующими разделами:

Частичную отрисовку страницы можно включить с помощью серверных веб-элементов управления UpdatePanel и ScriptManager. Элемент управления UpdatePanel определяет область страницы, которая может быть обновлена. Элемент управления ScriptManager отслеживает элементы управления UpdatePanel, расположенные на странице, и элементы управления, которые инициируют обновление элементов управления UpdatePanel. Элементы управления внутри элемента управления UpdatePanel, который вызывает обратную передачу, автоматически определяются как триггеры для панели обновления. Кроме того, можно указать элементы управления, которые находятся вне элемента управления UpdatePanel. Внешние триггеры могут быть дочерними элементами управления другого элемента управления UpdatePanel. Дополнительные сведения см. в разделах Общие сведения о частичной отрисовке страниц и Общие сведения об элементе управления UpdatePanel.

Содержание раздела:

Ограничения на число элементов управления UpdatePanel, которые можно поместить на страницу, не существует. В результате можно указать области страницы, которые обновляются независимо от всей страницы и независимо друг от друга.

По умолчанию свойство UpdateMode элемента управления UpdatePanel имеет значение Always. Это означает, что всякий раз, когда инициируется частичное обновление страницы, элемент управления UpdatePanel обновляет страницу, даже если триггер предназначался не для этого элемента управления UpdatePanel. Чтобы убедиться, что элемент управления UpdatePanel обновляется только при срабатывании триггера, можно задать для свойства UpdateMode элемента управления UpdatePanel значение Conditional.

В следующем примере используется два элемента управления UpdatePanel. Один элемент управления включает веб-элементы управления, которые принимают пользовательский ввод, а другой элемент управления отображает то, что ввел пользователь. У каждого элемента управления UpdatePanel есть свойство UpdateMode со значением Conditional.. В результате, если пользователь нажимает кнопку Отменить для очистки полей формы ввода, то обновляется только форма ввода элемента управления UpdatePanel. Если пользователь нажимает кнопку Вставить для отправки формы, то обновляются оба элемента управления UpdatePanel.

<%@ 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>


Кроме того, можно вложить элемент управления UpdatePanel в другой элемент управления UpdatePanel. Если как для внешних, так и для вложенных элементов управления задать свойство UpdateMode со значением Conditional, то внешняя панель не обновляется при срабатывании триггера внутренней панели. Однако, если триггер обновляет внешнюю панель, то обновляются, как внешняя, так и внутренняя панели.

В следующем примере элемент управления GridView находится внутри элемента управления UpdatePanel. Каждая строка элемента управления GridView содержит вложенный элемент управления GridView, который находится внутри дочернего элемента управления UpdatePanel. При запросе новой страницы записей из внутреннего элемента управления GridView области страницы внешней панели и панелей в других строках внешнего элемента управления GridView не обновляются. При отображении новой страницы записей внешним элементом управления GridView области страницы внешней панели и вложенных панелей обновляются.

<%@ 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>


Элементы управления внутри элемента управления UpdatePanel, который инициирует обратную передачу, автоматически настраиваются как триггеры для элемента управления UpdatePanel. Однако может потребоваться отключение автоматических триггеров и установка триггера на обновления элемента управления UpdatePanel только из внешнего элемента управления. Для этого следует задать для свойства ChildrenAsTriggers элемента управления UpdatePanel значение false. Затем необходимо задать для свойства UpdateMode элемента управления UpdatePanel значение Conditional. Такие параметры свойств приведут к обновлению панели, только если сработает триггер внешнего элемента управления или если будет вызван метод Update.

В следующем примере показаны категории, подкатегории и имена продуктов из примера базы данных AdventureWorks. Список категорий изменяется редко, и поэтому отсутствует необходимость обновлять его каждый раз при отображении списка подкатегорий или продуктов. Таким образом, в элементе управления UpdatePanel, содержащем список категорий, можно задать свойство ChildrenAsTriggers в значение false, а свойство UpdateMode в Conditional. Это гарантирует, что элемент управления UpdatePanel обновляется только при явном запросе.

<%@ 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>


Элементы управления, которые вызывают обновления элемента управления UpdatePanel, должны быть зарегистрированы с элементом управления ScriptManager на странице. Это происходит автоматически для дочерних элементов управления в элементе управления UpdatePanel. Можно указать триггеры декларативно, используя коллекцию Triggers элемента управления UpdatePanel. Кроме того, можно программно определять триггеры и использовать серверный код, чтобы обновить элемент управления UpdatePanel.

В случаях, когда триггер элемента управления не доступен во время разработки, можно зарегистрировать элемент управления в виде триггера с помощью метода RegisterAsyncPostBackControl элемента управления ScriptManager. Элементы управления, которые идентифицируются программно как триггеры, должны регистрироваться каждый раз, когда происходит обратная передача. Рекомендуется поместить вызовы метода RegisterAsyncPostBackControl в событие Page_Load для страницы, как показано в следующем примере:

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


Чтобы программно обновить элемент управления UpdatePanel, можно вызвать метод Update элемента управления UpdatePanel. Это полезно, если необходимо выполнить некоторую обработку на сервере перед обновлением элемента управления UpdatePanel. Следующий пример демонстрирует обновление UpdatePanel программными средствами.

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();
}


В следующем примере показана страница, которая регистрирует элемент управления в виде триггера с помощью метода RegisterAsyncPostBackControl. Затем она программно обновляет элемент управления UpdatePanel с помощью метода Update.

<%@ 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>


Можно добавить UpdatePanel в пользовательский элемент управления или в настраиваемый элемент управления. Однако страница, содержащая элемент управления, не может включать необходимый элемент управления ScriptManager со свойством EnablePartialRendering, имеющим значение true. Таким образом, в пользовательском элементе управления можно определить включена ли отрисовка частичных страниц с помощью вызова статического метода GetCurrent элемента управления ScriptManager. Если на странице нет элемент управления ScriptManager, то метод GetCurrent возвращает null. В противном случае можно проверить значение свойства EnablePartialRendering элемента управления ScriptManager и включить элемент управления UpdatePanel, если свойство EnablePartialRendering возвращает значение true.

В следующем примере показан метод CreateChildControls пользовательского элемента управления, наследуемого от класса CompositeControl. Если для страницы частичная отрисовка включена, то пользовательский элемент управления помещает ее содержимое в элемент управления UpdatePanel.

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);
}


В следующем примере показан пользовательский элемент управления, содержащий элемент управления UpdatePanel, если отрисовка частичных страниц включена.

<%@ 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);
        }
    }
}


Показ: