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. Instead of just using List and ObjectList to display a textual list of items, using templates you can completely replace the default rendering of the list's contents.

The List and ObjectList controls support the use of the templates described in Table 10-1:

























Table 10-1: Templates Supported by the Templated Controls


< HeaderTemplate>


<HeaderTemplate> is rendered at the top of the list. When you enable pagination, the template is rendered at the head of the list on each page.


<FooterTemplate>


<FooterTemplate> is rendered at the bottom of the list. When you enable pagination, the template is rendered at the foot of the list on each page.


<ItemTemplate>


You use <ItemTemplate> to render each item.


<AlternatingItemTemplate>


If specified, the application uses this template to render even-numbered items—the second item, the fourth item, and so on.


<SeparatorTemplate>


The <SeparatorTemplate> is rendered between each item.


<ItemDetailsTemplate> (ObjectList only)


You use <ItemDetailsTemplate> to render the Details view in an ObjectList control.


You'll normally use templates to enhance the data presentation on a particular browser. To do this effectively, you need both an understanding of the markup that the client requires and the functionality that you want the list to provide.


Programming the List Control Templates


Back in Chapter 6 when we first looked at how to use the List control, Listing 6-7 in that section showed a simple application called ListItemCommandExample.aspx file that did not use templates. The application displays a simple list of team names. When the user selects an item from the list, additional details appear on a second form, as Figure 10-3 shows. Although not particularly eye-catching, the default rendering is functional.


Figure 10-3: Default rendering of ListItemCommandExample.aspx

Using templates can greatly enhance your list presentation. In the following example, we use <HeaderTemplate> to output markup to open an HTML <table> and to display a graphic in the first row of the table. We use the <ItemTemplate> and <AlternatingItemTemplate> templates to inject the tags for HTML table items (<td>…</td>) and rows (<tr>…</tr>) and to apply different colors and fonts. <SeparatorTemplate> creates a visually appealing divider bar, and <FooterTemplate> closes the HTML table. Listings 10-3 and 10-4 show how to implement these templates.

Listing 10-3: Source file TemplatedListExample.aspx






<%@ Page Inherits="MSPress.MobWeb.TemplateListEx.ExampleWebForm"
Language="c#" CodeBehind="TemplatedListExample.aspx.cs"%>
<%@ Register TagPrefix="mobile"
Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<mobile:Form id="Form1" runat="server">
<mobile:Label runat="server" StyleReference="title">
Season 2003 results
</mobile:Label>
<mobile:List id="List1" runat="server"
DataTextField="TeamName"
DataValueField="Stats">
<DeviceSpecific>
<Choice Filter="isHTML32">
<HeaderTemplate>
<table width="100%">
<tr><td><img align="left"
src="title.gif"
width="440" height="70"/>
</td></tr>
</HeaderTemplate>
<ItemTemplate>
<tr><td bgcolor="#00c0c0"><font face="Arial">
<b><asp:LinkButton runat="server">
<%# ((MobileListItem)Container).Text %>
</asp:LinkButton></b>
</font></td></tr>
</ItemTemplate>
<AlternatingItemTemplate>
<tr><td bgcolor="#ffc080"><font face="Arial">
<b><asp:LinkButton runat="server">
<%# ((MobileListItem)Container).Text %>
</asp:LinkButton></b>
</font></td></tr>
</AlternatingItemTemplate>
<SeparatorTemplate>
<tr><td>
<img align="left" src="divider.gif"
width="440" height="10"/>
</td></tr>
</SeparatorTemplate>
<FooterTemplate>
<tr><td>
<img align="left" src="divider.gif"
width="440" height="10"/>
</td></tr>
</table>
</FooterTemplate>
</Choice>
</DeviceSpecific>
</mobile:List>
</mobile:Form>
<mobile:Form runat="server" id="Form2">
<mobile:Label runat="server">Teams Full Stats:</mobile:Label>
<mobile:Label runat="server" id="Label1" />
</mobile:Form>











Listing 10-4: Code-behind file TemplatedListExample.aspx.cs






using System;
using System.Collections;
using System.Web.UI.MobileControls;
namespace MSPress.MobWeb.TemplateListEx
{
public class ExampleWebForm : System.Web.UI.MobileControls.MobilePage
{
protected Label Label1;
protected List List1;
protected Form Form1;
protected Form Form2;
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
this.List1.ItemCommand +=
new ListCommandEventHandler(this.ClickTeamSelection);
}
protected void Page_Load(Object sender, EventArgs e)
{
if (!IsPostBack)
{
ArrayList array = new ArrayList();
array.Add(new TeamStats("Dunes", "Posn:1 Pl:38 Pts:80"));
array.Add(new TeamStats("Phoenix", "Posn:2 Pl:38 Pts:70"));
array.Add(new TeamStats("Eagles", "Posn:3 Pl:38 Pts:69"));
array.Add(new TeamStats("Zodiac", "Posn:4 Pl:38 Pts:68"));
List1.DataSource = array;
List1.DataBind();
}
}
protected void ClickTeamSelection(
Object source,
ListCommandEventArgs args)
{
//Display the Stats page
this.ActiveForm = Form2;
Label1.Text = args.ListItem.Text + ": " + args.ListItem.Value;
}
}
public class TeamStats
{
private String teamName, stats;
public TeamStats(String teamName, String stats)
{
this.teamName = teamName;
this.stats = stats;
}
public String TeamName
{
get { return this.teamName; }
}
public String Stats
{
get { return this.stats; }
}
}
}











Templates must always be coded inside <Choice> elements of a DeviceSpecific/Choice construct. The server control syntax in Listing 10-3 includes a DeviceSpecific/Choice filter so that the templates are used only for HTML 3.2 client devices; however, this application still works fine on other devices using the List control's default rendering. Figure 10-4 shows how this code output looks on an HTML 3.2 browser.


Figure 10-4: Presentation on an HTML 3.2 browser enhanced by using templates

If you want the template to apply to all devices, code the template inside the default <Choice> element, as in the following example:

    <mobile:List id="List1" runat="server"> 
<DeviceSpecific>
<Choice>
<HeaderTemplate>


</HeaderTemplate>
</Choice>
</DeviceSpecific>
</mobile:List>


Displaying Data Values in Templates


The contents of <ItemTemplate> and <AlternatingItemTemplate> need more explanation. Let's examine the <ItemTemplate> template in Listing 10-3 in more detail:

    <ItemTemplate>
1 <tr><td bgcolor="#00c0c0"><font face="Arial">
2 <b><asp:LinkButton runat="server">
3 <%# ((MobileListItem)Container).Text %>
2 </asp:LinkButton></b>
1 </font></td></tr>
</ItemTemplate>

This code displays the list item within the markup for an HTML table row, and consists of three distinct parts:



The 1 lines (of the code) are just HTML markup that is used to format the list item as an HTML table cell, and to set the font to Arial.



The first 2 line contains a <b> tag to start bold formatting, and then the tags for a regular (not mobile) ASP.NET LinkButton control. The second 2 line contains the closing tags for these elements. The ASP.NET LinkButton is there to maintain the interactivity of the list, so the user can click on an item to select it. We'll examine this in more detail in the section "Enabling OnItemCommand Events in Templates" later in this chapter.



The 3 line contains special tags <%# … %> which indicates that this is an ASP.NET data binding statement; inside these tags you place program code that returns a data value. In this case the code is ((MobileListItem)Container).Text; we'll look at what this is and how it works now.



When you define an item template, it completely replaces the normal default rendering of the list item. Inside the item template, you must include code to display the data item as a part of your template. In this particular example, you achieve this by using ASP.NET data binding syntax <%# … %>. We'll look at ASP.NET data binding syntax in more detail in the next chapter, but for now, all you need to know is that the runtime evaluates the contents of this syntax when the DataBind method of the containing list control executes (called within the Page_Load method in Listing 10-4). The data binding syntax used here extracts the underlying data item using the syntax <%# ((MobileListItem)Container).Text %>, which to the ASP.NET page parser means: get the Container property of this template item, cast it to a MobileListItem object, and then get the Text property of the MobileListItem object. The Text property of the MobileListItem returns the value of the data item to display. The Container variable has a special meaning in templates, as we'll explain shortly.

Understanding Template ContainersA List control stores all the items in the list in a collection of MobileListItem objects. An ObjectList control stores its list items in a collection of ObjectListItem objects. Both the MobileListItem and the ObjectListItem objects are descended from the System.Web.UI.MobileControls.TemplateContainer class, which indicates that they can act as a container for templates. Whenever you define an <ItemTemplate> or <AlternatingItemTemplate> template, the contents of the template is instantiated as a child object of each MobileListItem or ObjectListItem object of that list control. In any ASP.NET data binding expression within a template, you can use the variable Container, which points to the containing MobileListItem or ObjectListItem object. In our example, you use the Container variable to access the enclosing MobileListItem object.

You must cast the Container variable to the correct type, MobileListItem. You can then use this variable to access properties of MobileListItem. The code accesses the Text property, ((MobileListItem)Container).Text, which is the default display value of the MobileListItem object. In the example shown earlier in Listing 10-3 and 10-4, the List control is programmed to display the TeamName property of the underlying data class, and so the Text property of the MobileListItem returns the name of the team.

In Visual Basic, you need to use the CType function to perform the casting:

<ItemTemplate>
<%# CType(Container, MobileListItem).Text %>
</ItemTemplate>

See the C# and Visual Basic samples DataBindingInTemplateExample in the companion materials on this book's Web site for applications that use this technique.





Tip

It's a common programming error to forget to call the DataBind method. To evaluate data binding expressions, you must call the DataBind method of the containing control. The previous example simply calls DataBind for the List1 control, but usually, calling the DataBind method of the mobile page within the Page_Load event handler is sufficient because doing so also calls the DataBind method of all enclosed controls. The following code illustrates this concept:


protected void Page_Load(Object sender, EventArgs e)
{
this.DataBind();
}





Tip

See the section "Using ASP.NET Declarative Data Binding" in the next chapter for more information.


Enabling OnItemCommand Events in Templates


When applying item templates, the final step is to ensure that the OnItemCommand capability remains intact. In the default rendering, the user clicks a list item to access another page. You can trap the ItemCommand event and execute code in your application as a result. However, if you write an <ItemTemplate> similar to the following, it simply displays the data value of the list item, and the templated version of the list becomes a static list display without any interactivity:

         <ItemTemplate>
<%# ((MobileListItem)Container).Text %>
</ItemTemplate>

The template for a list item must therefore incorporate an interactive control as well as the data to display. A mobile Command control might seem like a good choice, as it is rendered on all mobile clients; however, this control is rendered as a button. The perfect choice is the ASP.NET LinkButton control, which renders the item as a hyperlink, as required. The LinkButton control's Click event bubbles up to its parent control, allowing you to use the same event handler. The final version of the <ItemTemplate> templateexcluding HTML markup to manipulate style attributes—now reads as follows:

<ItemTemplate>
<tr><td>
<asp:LinkButton runat="server" id="LinkButton1">
<%# ((MobileListItem)Container).Text %>
</asp:LinkButton>
</td></tr>
</ItemTemplate>








Event Handling for Controls Embedded in Templates


Certain mobile control events support ASP.NET's event bubbling capability. For example, the mobile Command control supports two events: Click and ItemCommand. The ItemCommand event bubbles up; the Click event doesn't. Event handlers for events that can bubble up take an argument that descends from System.Web.UI.WebControls.CommandEventArgs. The event handler for the List control ItemCommand event takes an argument of type ListCommandEventArgs, which descends from CommandEventArgs. You can embed any control that raises an event that bubbles up, and the parent control's event handler can trap it.

If you have an event handler that handles events from a number of controls, you can identify the source of the event using the CommandName property of the System.Web.UI.WebControls.CommandEventArgs object. The CommandName property is set to null when an ItemCommand event of the List control is raised when no templates are used. However, if you embed a control such as the ASP.NET LinkButton control or the ASP.NET mobile controls Command control (which both support event bubbling), you can specify a CommandName property, which passes to the event handler in the CommandEventArgs argument object.

This way, your event handler code can distinguish between events raised through the default rendering (where the CommandName property is null) and those raised by controls contained within templates.












Programming the ObjectList Control Templates


Most of the techniques we have just seen for use with the List control, apply too to the ObjectList control. However, the List control is designed to display a listing of the values of a single field from the data source, whereas the ObjectList is used to display many fields for a data item, and this makes the programming of templates slightly different.

The ObjectList control supports the same templates as the List control, and it also supports the <ItemDetailsTemplate> for customizing the data item details view.

Displaying Data Values in ObjectList Control Templates


In general, the technique for displaying fields in the <ItemTemplate> and <AlternatingItemTemplate> templates with the ObjectList control is the same as the List control technique. In the previous example, you saw that the MobileListItem object that contains a single item in the list for a List control has Text and Value properties that expose the two fields used for the DataTextField and DataValueField properties, respectively.

The ObjectList control is designed to show multiple fields for a single data item, so the ObjectListItem object that contains a single item in the list actually contains a collection of strings, one for each field from the data source that the control will display. Consequently, to display a specific field inside an <ItemTemplate> or <AlternatingItemTemplate> template, you must index into that collection using the field name as the index, as shown here:

<ItemTemplate>
<%# ((ObjectListItem)Container)["fieldname"] %>
</ItemTemplate>

Listings 10-5 and 10-6 show a simple application that uses an ObjectList control and templates. In fact, the use of the <ItemTemplate> in this example does not introduce any customization of the output of the ObjectList control, but it serves to illustrate how to program ObjectList templates.

Listing 10-5: Source file ObjectListTemplateExample.aspx






<%@ Page language="c#" Codebehind="ObjectListTemplateExample.aspx.cs" 
Inherits="MSPress.MobWeb.ObjListTemplEx.ObjectListTemplateExample"
AutoEventWireup="false" %>
<%@ Register TagPrefix="mobile" Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<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">
<DeviceSpecific>
<Choice>
<ItemTemplate>
<asp:LinkButton id="LinkButton1" Runat="server">
<%# ((ObjectListItem)Container)["TeamName"] %>
</asp:LinkButton>
<br>
</ItemTemplate>
</Choice>
</DeviceSpecific>
</mobile:ObjectList>
</mobile:form>











Listing 10-6: Code-behind file ObjectListTemplateExample.aspx.cs






using System;
using System.Collections;
using System.Web.UI.MobileControls;
namespace MSPress.MobWeb.ObjListTemplEx
{
public class ObjectListTemplateExample :
System.Web.UI.MobileControls.MobilePage
{
protected System.Web.UI.MobileControls.ObjectList ObjectList1;
protected System.Web.UI.MobileControls.Label Label1;
protected System.Web.UI.MobileControls.Form Form1;
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.ObjectList1.ItemCommand += new
ObjectListCommandEventHandler(this.ObjectList1_ItemCommand);
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";
this.DataBind();
}
}
private void ObjectList1_ItemCommand
(object sender, ObjectListCommandEventArgs e)
{
ObjectList1.SelectedIndex = e.ListItem.Index;
ObjectList1.ViewMode = ObjectListViewMode.Details;
}
}
class TeamStats
{
private String _teamName;
private int _position, _played, _won, _drawn, _lost, _points;
public TeamStats(String teamName,
int position,
int played,
int won,
int drawn,
int lost,
int points)
{
this._teamName = teamName;
this._position = position;
this._played = played;
this._won = won;
this._drawn = drawn;
this._lost = lost;
this._points = points;
}
public String TeamName { get { return this._teamName; } }
public int Position { get { return this._position; } }
public int Played { get { return this._played; } }
public int Won { get { return this._won; } }
public int Drawn { get { return this._drawn; } }
public int Lost { get { return this._lost; } }
public int Points { get { return this._points; } }
}
}











Enabling OnItemCommand Events in Templates with the ObjectList Control


To make a templated ObjectList control raise a Command event, you use an ASP.NET LinkButton control, just as you do with the List control. However, if you want to retain the default behavior of the ObjectList control so that clicking an item in the list displays the Details view, you must write some more code.

In the example just shown in Listing 10-5, the <ItemTemplate> template contains the following code:

               <ItemTemplate>
<asp:LinkButton id="LinkButton1" Runat="server">
<%# ((ObjectListItem)Container)["TeamName"] %>
</asp:LinkButton>
<br>
</ItemTemplate>

The ObjectList control raises the ItemCommand event when an item in the list is selected. Inside your event handler method, you must include the following code to switch the display to the Details view (as demonstrated in Listing 10-6):

private void ObjectList1_ItemCommand(
object sender,
System.Web.UI.MobileControls.ObjectListCommandEventArgs e)
{
ObjectList1.SelectedIndex = e.ListItem.Index;
ObjectList1.ViewMode = ObjectListViewMode.Details;
}

This code sets the SelectedIndex property of the ObjectList control to the item the user clicked, and it sets the ViewMode property so that the Details view is displayed.


Using the ObjectList Control's <ItemDetailsTemplate>


By default, the Details view of an item selected from an ObjectList control is displayed as a separate page, appearing as a table on HTML browsers and as a simple list of static text on WML browsers. When you specify an <ItemDetailsTemplate> template, you replace the entire details page rather than just a single row of a table, as occurs with the <ItemTemplate> template. Listings 10-7 and 10-8 show you how to do this.

Listing 10-7: Source file ObjectListItemDetailsTemplateExample.aspx






<%@ Page Inherits="MSPress.MobWeb.ObLItemDetTemplate.MyWebForm"   
CodeBehind="ObjectListItemDetailsTemplateExample.aspx.cs"
Language="c#" %>
<%@ Register TagPrefix="mobile" Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<mobile:Form runat="server" id="Form1">
<mobile:Label runat="server" StyleReference="title">
Season 2003 results</mobile:Label>
<mobile:ObjectList id="ObjectList1" runat="server"
AutoGenerateFields="false">
<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>
<DeviceSpecific>
<Choice>
<ItemDetailsTemplate>
<%# DataBinder.Eval(
((ObjectList)Container.NamingContainer).Selection.DataItem,
"TeamName", "Team : {0}") %>
<br/>
<%# DataBinder.Eval(
((ObjectList)Container.NamingContainer).Selection.DataItem,
"Won", "Won : {0}") %>
<br/>
<%# DataBinder.Eval(
((ObjectList)Container.NamingContainer).Selection.DataItem,
"Drawn", "Drawn: {0}") %>
<br/>
<%# DataBinder.Eval(
((ObjectList)Container.NamingContainer).Selection.DataItem,
"Lost", "Lost : {0}") %>
</ItemDetailsTemplate>
</Choice>
</DeviceSpecific>
</mobile:ObjectList>
</mobile:Form>











Listing 10-8: Code-behind file ObjectListItemDetailsTemplateExample.aspx.cs






using System;
using System.Collections;
using System.Web.UI;
using System.Web.UI.MobileControls;
namespace MSPress.MobWeb.ObLItemDetTemplate
{
public class MyWebForm : System.Web.UI.MobileControls.MobilePage
{
protected ObjectList ObjectList1;
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
protected void Page_Load(Object sender, EventArgs e)
{
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";
ObjectList1.DataBind();
}
}
public class TeamStats
{
private String _teamName;
private int _position, _played, _won, _drawn, _lost, _points;
public TeamStats(String teamName,
int position,
int played,
int won,
int drawn,
int lost,
int points)
{
this._teamName = teamName;
this._position = position;
this._played = played;
this._won = won;
this._drawn = drawn;
this._lost = lost;
this._points = points;
}
public String TeamName { get { return this._teamName; } }
public int Position { get { return this._position; } }
public int Played { get { return this._played; } }
public int Won { get { return this._won; } }
public int Drawn { get { return this._drawn; } }
public int Lost { get { return this._lost; } }
public int Points { get { return this._points; } }
}
}











In this example, the <ItemDetailsTemplate> template contains the following ASP.NET data binding syntax to access the underlying data item the user selects. It uses the DataBinder.Eval method to simplify data binding syntax—see the sidebar later on for an explanation of how to use DataBinder.Eval.

<ItemDetailsTemplate>
Played: <%# DataBinder.Eval(
((ObjectList)Container.NamingContainer).Selection.DataItem, "Played") %>
</ItemDetailsTemplate>

In the earlier example shown in Listing 10-5 that demonstrated the use of the <ItemTemplate>, the code used to access the data item cast the Container variable to an ObjectListItem:

     <ItemTemplate>
<asp:LinkButton id="LinkButton1" Runat="server">
<%# ((ObjectListItem)Container)["TeamName"] %>
</asp:LinkButton>
<br>
</ItemTemplate>

The situation is different with the <ItemDetailsTemplate> of the ObjectList control. You use this template to format the "all fields'" form that's displayed after the user selects an item from the list. Here the display of the data item's field detail is a logically separate operation that occurs outside the data listing, after the user selects an item from the list. You can't cast to the ObjectListItem class to access the individual field items of the selected list entry; in the details view, there is no ObjectListItem. Instead, you must access the item through the parent control—in this case, the ObjectList control.

The way you obtain access to the parent control from within the <ItemDetailsTemplate> template requires some explanation. Controls in a mobile Web Forms page are organized hierarchically, and each control has a parent control. At the top of the hierarchy lies the instance of the MobilePage class that's created when the user first accesses the page. Each control on a mobile Web Forms page must have a unique ID. The parent control that implements the System.Web.UI.INamingContainer interface enforces the uniqueness of the child control's ID. (This parent control often is the underlying MobilePage control.) The control that implements INamingContainer creates a namespace that uniquely identifies the controls it contains. This is particularly important with list controls because the runtime creates many similar controls to present each line of data. For this reason, the List and ObjectList controls implement INamingContainer.

Every control inherits the NamingContainer property from the System.Web.UI.Control base class. This property returns a reference to the parent control above it in the hierarchy that provides its naming context. In an <ItemDetailsTemplate> template, you use the syntax Container.NamingContainer to reference the parent ObjectList control. This is because the Container variable references the TemplateContainer in which you've instantiated the template, and the NamingContainer property returns a reference to the parent ObjectList. You can then access properties and methods of the parent ObjectList, as shown in this example:

<ItemDetailsTemplate>
Played: <%# DataBinder.Eval(
((ObjectList)Container.NamingContainer).Selection.DataItem, "Played") %>
</ItemDetailsTemplate>

Here's how the same example looks in Visual Basic:

<ItemDetailsTemplate>
Played: <%# DataBinder.Eval(
CType(Container.NamingContainer,ObjectList).Selection.DataItem, "Played") %>
</ItemDetailsTemplate>

Using this technique, properties of the ObjectList control, such as Selection, are accessible and allow the individual fields of the selected data item to be accessed and displayed.

The output of this application is shown in Figure 10-5. This application illustrates a technique, so the output is less impressive than the default ObjectList rendering. With <ItemDetailsTemplate>, you have complete control over the content of the Details view.


Figure 10-5: Output of the ObjectListItemDetailsTemplateExample application, with the Details view replaced by the contents of <ItemDetailsTemplate>








Simplifying Data Binding Syntax with DataBinder.Eval


The DataBinder.Eval statement in the example is a static method of the System.Web.UI.DataBinder class that eliminates much of the complicated explicit type casting that data binding syntax often requires. Although this static method is easier to use than explicit type casting, this usability comes at a price. DataBinder.Eval uses late-bound reflection, which is a technique that allows the type of an object to be determined at run time rather than explicitly casting the object to the correct type at compile time. The object is then converted to a string representation, consequently incurring a performance overhead.

The DataBinder.Eval static method is particularly useful when you're working with data items in templates. For example, consider an <ItemTemplate> template that retrieves an integer item from the underlying data source:

<ItemTemplate>
<%# String.Format("{0:N2}",
((MobileListItem)Container).DataItem["Points"] %>
</ItemTemplate>

This syntax can be hard to remember. Using DataBinder.Eval simplifies the code a little:

<ItemTemplate>
<%# DataBinder.Eval(((MobileListItem)Container).DataItem,
"Points", "{0:N2}" ) %>
</ItemTemplate>

The first parameter is the naming container for the data item. (We'll talk about naming containers in the section "Working with Controls in Templates Programmatically.") The second parameter is the data field name, and the third parameter is an optional formatting string. If you omit the third parameter, DataBinder.Eval returns a result of type object.











/ 145