Building Microsoft ASP.NET Applications for Mobile Devices, Second Edition [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Building Microsoft ASP.NET Applications for Mobile Devices, Second Edition [Electronic resources] - نسخه متنی

Andy Wigley; Peter Roxburgh

نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
تنظیمات قلم


اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
افزودن یادداشت
افزودن یادداشت جدید

Chapter 9, in the "Working with Controls in Form and Panel Templates" section, you learned why it is not as simple as you might think to write code that sets or gets properties of controls placed in templates. For example, if you have a Label control inside a template with the ID Label2, you can't use code like this:

Label2.Text = "A suitable heading";

In fact, this returns a run-time error, stating that Label2 is a null object. This is because controls inside templates are not child controls of the Form, but instead are instantiated inside each of the MobileListItem objects (or ObjectListItem objects in the case of the ObjectList control) that are created to contain the items in the list. The controls defined in templates are hidden down the control tree, so to address them in code, you must use the System.Web.UI.Control.FindControl method.

The situation is more complicated in the case of the list controls than it is with the templates of the Form and Panel controls. With lists, an <ItemTemplate>, an <AlternatingItemTemplate>, or a <SeparatorTemplate> template is instantiated each time it is used—in other words, for every item in the list. If you have a Label control inside one of these templates with an ID of Label2, you might expect a naming clash because a list of, say, five items would end up with five instances of a Label control with the same ID, which isn't allowed.

ASP.NET handles this situation by giving certain controls the ability to establish a naming context. Such a control has the ability to ensure that all child controls have a unique ID by prefixing the assigned ID of the child control with its own ID. For instance, in the previous example, the TemplateContainer child control of the List1 object can have a system assigned ID of ctrl0, so the Label control has a unique ID of List1:ctrl0:Label2. The NamingContainer object for the <ItemTemplate>, <AlternatingItemTemplate>, or <SeparatorTemplate> template of the List and ObjectList controls is the MobileListItem or ObjectListItem object that is present for each list item; you can access these objects through each control's Items collection. The NamingContainer object for the <HeaderTemplate> and <FooterTemplate> templates of the List and ObjectList controls is a TemplateContainer child control, which is also the NamingContainer object for the ObjectList control's <ItemDetailsTemplate>.

If you can find the object that provides the naming container, you can use the FindControl method of System.Web.UI.Control (the parent class of MobileControl) to locate specific child controls within that naming context.


If you're finding it difficult to understand the control hierarchy within a Web Forms page, turn on the trace facility, as described in Chapter 16. Part of the trace output is a listing of the full control hierarchy, which is a great help when you're working with child controls and naming contexts.

Accessing Controls in List and ObjectList Templates from Code

Consider the .aspx file shown in Listing 10-9, which uses an ObjectList control with an <ItemTemplate> template that contains a Label control with the ID Label2. We want to display the data as a numbered list, so we'll use the Label2 control that's included in the template to display the line number.

Listing 10-9: Source file ObjectListTemplateControlsFromCode.aspx

<%@ Register TagPrefix="mobile" Namespace="System.Web.UI.MobileControls" 
Assembly="System.Web.Mobile" %>
<%@ Page Codebehind="ObjectListTemplateControlsFromCode.aspx.cs"
language="c#" AutoEventWireup="false" %>
<mobile:form id="Form1" runat="server">
<mobile:Label id="Label1" runat="server" StyleReference="title">
Season 2003 results</mobile:Label>
<mobile:ObjectList id="ObjectList1" runat="server"
<Choice Filter="isHTML32">
<table width="90%">
<mobile:Label id="Label2" Runat="server"/>
<asp:LinkButton id="LinkButton1" Runat="server">
<%# ((ObjectListItem)Container)["TeamName"] %>
<Field Title="Team" DataField="TeamName"></Field>
<Field Title="Won" DataField="Won"></Field>
<Field Title="Drawn" DataField="Drawn"></Field>
<Field Title="Lost" DataField="Lost"></Field>
<Field Title="Points" DataField="Points" Visible="False"></Field>

You can't trap the DataBind event and set the Text property of the Label2 control to the required value because at the point in the control's life cycle when the DataBind event executes, the contents of the template have not yet been instantiated. Instead, let the control build the list of items, and then trap the PreRender event that's raised after all other processing on the server has completed and just before the output to be sent to the client is rendered.

In the PreRender event handler, we can enumerate the collection of ObjectListItem objects (exposed by the ObjectList.Items property). The contents of the template have by now been instantiated as child controls of the ObjectListItem object, so we use FindControl to locate the Label2 control and set its Text property to the required value. This process is illustrated in Listing 10-10:

Listing 10-10: Code-behind file ObjectListTemplateControlsFromCode.aspx.cs

using System;
using System.Collections;
using System.Web.UI.MobileControls;
namespace MSPress.MobWeb.OblTemplateCtrlsEx
public class MyWebForm : System.Web.UI.MobileControls.MobilePage
protected System.Web.UI.MobileControls.Label Label1;
protected System.Web.UI.MobileControls.ObjectList ObjectList1;
protected System.Web.UI.MobileControls.Form Form1;
override protected void OnInit(EventArgs e)
private void InitializeComponent()
this.ObjectList1.PreRender += new
this.ObjectList1.ItemCommand += new
this.Load += new System.EventHandler(this.Page_Load);
protected void Page_Load(Object sender, EventArgs e)
if (!this.IsPostBack)
ArrayList array = new ArrayList();
array.Add(new TeamStats("Dunes",1,38,24,8,6,80));
array.Add(new TeamStats("Phoenix",2,38,20,10,8,70));
array.Add(new TeamStats("Eagles",3,38,20,9,9,69));
array.Add(new TeamStats("Zodiac",4,38,20,8,10,68));
ObjectList1.DataSource = array;
ObjectList1.LabelField = "TeamName";
private void ObjectList1_PreRender(object sender, System.EventArgs e)
// Walk the Items collection of the ObjectList. This collection
// contains the items that are displayed.
int itemcounter =1;
foreach (ObjectListItem item in ObjectList1.Items)
Label lblInTemplate = item.FindControl("Label2") as Label;
if (lblInTemplate != null)
lblInTemplate.Text = itemcounter.ToString();
private void ObjectList1_ItemCommand(
object sender, ObjectListCommandEventArgs e)
// User has selected an item, so switch to details view.
// You only need to do this switch manually because we are
// using templates.
ObjectList1.SelectedIndex = e.ListItem.Index;
ObjectList1.ViewMode = ObjectListViewMode.Details;
class TeamStats
// Not shown – same as in listing 10-7


This example uses the ObjectList control, but you can use the same technique with the List control where you enumerate the List.Items collection in the PreRender event handler, which is a collection of MobileListItem objects.

/ 145