In some scenarios—for example, if you want to show the details of a
repeated data structure on demand—it may be tempting to put an UpdatePanel
control inside a repeated structure
such as a DataList
or a Repeater
control, which, let's face it, is not a
very good idea in most cases.
Sometimes, it's just better to place one big UpdatePanel
around the repeated structure and
update the whole thing on postbacks. Another option is the one shown in
the last example of the previous section, in which a unique external
UpdatePanel
can associate dynamically
with any item in the repeated structure (the DataList
in the example). This works and scales
well if you want only one details view to be visible at any given
time.
However, it is possible to dynamically create UpdatePanel
controls. This opens the possibility
of an UpdatePanel
control inside of the
template of a Repeater or DataList
(as
well as a few other scenarios like UpdatePanel
controls in WebParts). In Example 10, the template of a DataList
control contains a conditionally
updating UpdatePanel
control. The
template of the UpdatePanel
control
itself contains a label and a button. The click event handler for the
button modifies the text of the label and the button.
Example 10. Repeating an UpdatePanel control.
<%@ Page Language="C#" %> <%@ Import Namespace="System.Drawing" %> <%@ Import Namespace="System.ComponentModel" %> <script runat="server"> protected void ButtonClick(object sender, EventArgs args) { Button btn = (Button)sender; btn.Text = "Clicked"; ((Label)btn.NamingContainer.FindControl("ColorLabel")).Text = "Repeated panel updated at: " + DateTime.Now.ToLongTimeString(); } </script> <!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>Repeated UpdatePanel</title> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager runat="server" ID="SM1" /> <div> <asp:XmlDataSource runat="server" ID="data"> <Data> <colors> <color name="Red" value="#FF0000"/> <color name="Green" value="#00FF00"/> <color name="Blue" value="#0000FF"/> <color name="Cyan" value="#00FFFF"/> <color name="Purple" value="#FF00FF"/> <color name="Yellow" value="#FFFF00"/> </colors> </Data> </asp:XmlDataSource> <asp:DataList runat="server" ID="Repeat" DataSourceID="data" DataMember="color"> <ItemTemplate> <asp:UpdatePanel runat="server" ID="UP" UpdateMode="Conditional"> <ContentTemplate> <asp:Label runat="server" ID="ColorLabel" BackColor='<%# TypeDescriptor.GetConverter( typeof(System.Drawing.Color)).ConvertFromString((string)Eval("value")) %>' Text='<%# Eval("name") %>' /> <asp:Button runat="server" ID="PostInnerButton" Text="Post repeated panel" OnClick="ButtonClick" /> </ContentTemplate> </asp:UpdatePanel> </ItemTemplate> </asp:DataList> <asp:Button runat="server" ID="PostButton" Text="Postback" /> </div> </form> </body> </html>
Figure 16 shows how the page displays in a browser.
To get the equivalent sample in VB.NET, replace the server code with the following:
Protected Sub ButtonClick(ByVal sender As Object, ByVal args As EventArgs) Dim btn As Button = CType(sender, Button) btn.Text = "Clicked" CType(btn.NamingContainer.FindControl("ColorLabel"), Label).Text = _ "Repeated panel updated at: " & DateTime.Now.ToLongTimeString() End Sub
And replace the ColorLabel control with the following:
<asp:Label runat="server" ID="ColorLabel" BackColor='<%# TypeDescriptor.GetConverter(GetType(System.Drawing.Color)).ConvertFromString(Eval("val ue")) %>' Text='<%# Eval("name") %>' />
One caveat of this approach is that if the UpdatePanel
that triggered the asynchronous
postback is destroyed and recreated, ASP.NET Ajax may lose track of it and
the panel may not get updated. This can happen for example if the click
event handler for the button calls DataBind()
on the DataList
control.