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

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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






Using Templated Controls

The templated controls—Form, Panel, List, and ObjectList—offer additional capabilities for customization. These controls enable developers to define additional content to insert into a control's rendered representation at defined points. You can define content within the templates described in Table 9-3.










































Table 9-3: Templates Supported by the Templated Controls


Control


Template


Description


Form


<HeaderTemplate>


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


<FooterTemplate>


<FooterTemplate> is rendered at the foot of the form. When you enable pagination, this template is rendered at the foot of each page.


<ScriptTemplate>


<ScriptTemplate> is rendered at the top of the form. The content of <ScriptTemplate> is inserted directly after the <head> tag in HTML forms or after the opening <card> tag of a WML deck. When you enable pagination, this template is inserted at the head of each page.


Panel


<ContentTemplate>


You can use <ContentTemplate> to introduce blocks of device-specific markup. When specified, this template completely replaces any other contents of the Panel control.


List


<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.


ObjectList (same templates as a List control, with the addition of <ItemDetails Template>)


<ItemDetailsTemplate>


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


You must define all templates in a mobile Web Forms page as the body inside one of the <Choice></Choice> tags in a DeviceSpecific/Choice construct, as the following example illustrates:

<mobile:Form> <!-- or Panel, List, ObjectList-->
<mobile:DeviceSpecific>
<Choice Filter="filterName" OptionalPropertyOverrides go here >
<HeaderTemplate> <!-- Templates Go Here-->


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


You can use the templates listed in Table 9-3 in many ways. First, you can customize the appearance of pages and lists on all mobile devices. For example, you can insert generic mobile controls into a template to specify running headers and footers and to modify list presentation. In this case, the templates will contain only literal text and mobile controls.

Second, you can customize what is displayed on specific devices. When you use these templates within DeviceSpecific/Choice constructs, you can define template sets, which are customizations targeted at specific devices. You could opt to use only literal text and mobile controls in these templates—literal text and mobile controls work with any client device. However, if you use appropriate device filters in your DeviceSpecific/Choice constructs, you can include native device markup for rendering on the appropriate devices. These markup languages include HTML 3.2, compact HTML (cHTML) 1.0, WML 1.1, WML 1.2 or XHTML. For example, if you use the isHTML32 device filter, you can insert HTML 3.2 markup directly into the template, which the runtime then inserts into the markup sent to clients of the appropriate type.

Third, you can present data in tables on WML browsers. In their default rendering, the mobile controls don't present data in tables on WML browsers. Using the <HeaderTemplate>, <ItemTemplate>, and <FooterTemplate> elements of the List and ObjectList controls, you can specify the WML markup to present as a table on devices that support it.

Fourth, you can introduce whole blocks of client-side script or markup into your applications. Using the <ScriptTemplate> template of the Form control or the <ContentTemplate> of the Panel control, you can insert blocks of WML for execution on WML browsers, blocks of cHTML for use on i-mode devices, and blocks of HTML 3.2 for HTML browsers. You can also introduce blocks of JavaScript to execute on browsers that support it or calls to WMLScript resources on WAP devices.

Fifth, you can use regular (not mobile) ASP.NET controls. The ASP.NET controls can't operate with WML or cHTML browsers. But using a DeviceSpecific/Choice construct that selects HTML browsers enables you to apply nonmobile controls to devices that aren't mobile. And sixth, you can define your templates in a style defined in a style sheet and apply the templates to controls simply by setting the StyleReference property to the style containing the templates, just as you would with regular styles. This allows you to use a single style name to encapsulate a template set that combines templates for various devices.


Using the Form Control's <HeaderTemplate>, <FooterTemplate>, and <ScriptTemplate> Elements


You can use <HeaderTemplate> and <FooterTemplate> to specify content to appear at a page's top and bottom, respectively. If you set the Form.Pagination property to True, the templates will be rendered at the top and bottom of each page when pagination occurs. You can use <ScriptTemplate> to insert content directly after the <head> tag in HTML forms or after the opening <card> tag of a WML deck.

Implementing Running Headers and Footers


The simplest application of templates is to implement a basic running header and footer on each page. If you want all devices to support this functionality, you must use mobile controls, literal text, or a combination of the two. Listing 9-3 shows the code for this.

Listing 9-3: Source file SimpleFormTemplateExample.aspx






<%@ Register TagPrefix="mobile" 
Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<%@ Page language="c#"
Inherits="System.Web.UI.MobileControls.MobilePage" %>
<mobile:Form id="Form1" runat="server"
Paginate="True" BackColor="Khaki">
<mobile:TextView id="TextView1" runat="server">
This TextView control is on this form to demonstrate how
<b>&lt;HeaderTemplate&gt;</b> and <b>&lt;FooterTemplate&gt;</b>
elements on a Form control are used at the top and the bottom of
each page. <br/><br/>
If your application uses pagination (that is you've set
the <i>Paginate</i> property of the Form control to <i>true</i>),
the header and footer appear at the top and bottom of all pages.
<br/><br/>On HTML browsers, one thing you can do to enhance the
layout is to format the page as a table. The table is initiated in the
header template and closed in the footer template. Any content on the
page then appears as a table row.
</mobile:TextView>
<mobile:DeviceSpecific id="DeviceSpecific1" runat="server">
<Choice>
<HeaderTemplate>
<mobile:Label runat="server"
StyleReference="title"
ForeColor="Crimson">
This appears at the head of each page
</mobile:Label>
</HeaderTemplate>
<FooterTemplate>
<mobile:Label runat="server"
StyleReference="subcommand">
..and this at the foot of each page
</mobile:Label>
</FooterTemplate>
</Choice>
</mobile:DeviceSpecific>
</mobile:Form>











In Listing 9-3, the Form control contains a single TextView control, which contains a block of text to display. A DeviceSpecific/Choice construct within the Form control contains a single <Choice> element with no device filter applied, meaning that it will apply to all clients. Within this <Choice> element, the <HeaderTemplate> and <FooterTemplate> elements each contain a mobile Label control. Figure 9-7 shows how the output of this example looks on a Pocket PC and on an Openwave WML browser.


Figure 9-7: Content defined in the Form control <HeaderTemplate> and <FooterTemplate> elements rendered at the top and bottom of each page

Customizing Headers and Footers on Different Devices


To take this simple example a step further, we can introduce more <Choice> elements into the DeviceSpecific/Choice construct so that different <HeaderTemplate> and <FooterTemplate> elements apply to different devices. For example, you can easily enhance the DeviceSpecific/Choice construct used in Listing 9-3 to make the Label controls for the header and footer the default choice. Listing 9-4 is the same as Listing 9-3 except that it includes an additional <Choice> element in the DeviceSpecific/Choice construct, which, if the client browser is Pocket Internet Explorer, causes a GIF graphics file to be rendered for a header, instead of the Label controls defined in the default choice.

Listing 9-4: FormTemplateSetExample.aspx—a template set defining different <HeaderTemplate> elements for Pocket Internet Explorer and for the default choice






<%@ Register TagPrefix="mobile" 
Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<%@ Page language="c#"
Inherits="System.Web.UI.MobileControls.MobilePage"%>
<mobile:Form id="Form1" runat="server"
Paginate="True" BackColor="Khaki">
<mobile:TextView id="TextView1" runat="server">
This TextView control is on this form to demonstrate how
<b>&lt;HeaderTemplate&gt; </b>and <b>&lt;FooterTemplate&gt; </b>
elements on a <i>Form </i>control are used at the top and bottom of
each page. <br /><br />
If your application uses pagination (that is, you have set
the <i>Paginate </i>property of the <i>Form </i>control to true),
then the header and footer appear at the top and bottom of all pages.
<br /><br />On HTML browsers, one thing you can do to enhance the
layout is to format the page as a table. The table is initiated in the
header template and closed in the footer template. Any content on the
page then appears as a table row.
</mobile:TextView>
<mobile:DeviceSpecific id="DeviceSpecific1" runat="server">
<Choice Filter="isPocketIE">
<HeaderTemplate>
<mobile:Image runat="server" ImageUrl="AGoodHeader.gif"
AlternateText="A Good header">
</mobile:Image>
</HeaderTemplate>
</Choice>
<Choice>
<HeaderTemplate>
<mobile:Label runat="server"
StyleReference="title"
ForeColor="Crimson">
This appears at the head of each page
</mobile:Label>
</HeaderTemplate>
<FooterTemplate>
<mobile:Label runat="server"
StyleReference="subcommand">
This appears at the foot of each page
</mobile:Label>
</FooterTemplate>
</Choice>
</mobile:DeviceSpecific>
</mobile:Form>











Introducing Device-Specific Markup into a Template


If you use device filters to identify the particular markup that a client device requires (such as isHTML32, isCHTML10, and isWML11), the template can contain markup that is inserted into the page.

If you use the Form control templates to insert HTML markup, the rendered page sent to an HTML browser takes the following form:

<html>
<body>
<form…>
<!-- Content supplied in a ScriptTemplate goes here-->
<!-- Content supplied in a HeaderTemplate goes here-->
Rest of Form content
<!-- Content supplied in a FooterTemplate goes here-->
</form>
</body>
</html>

If you use the Form control templates to insert markup for WML browsers, the runtime inserts the markup this way:

<wml>
<card id=…>
<!-- Content supplied in a ScriptTemplate goes here-->
<p>
<!-- Content supplied in a HeaderTemplate goes here-->
Rest of Form content
<!-- Content supplied in a FooterTemplate goes here-->
<!-- Navigation <anchor> elements go here, if required.-->
</p>
</card>
</wml>

You saw this technique earlier, in Listing 9-2 where we used the isHTML32 device filter to insert HTML markup into the header and footer. Doing so formatted the HTML page as a table and then assigned HTML style attributes. Listing 9-2






<html><body>
<form id="_ctl0" name="_ctl0" method="post"
action="DeviceSpecificExample.aspx?__ufps=571483">


<table width="100%" height="100%" cellspacing="1">
<tr><td bgcolor="#003366">
<img src="sportsextra.gif">
</td></tr>
<tr><td bgcolor="#cccccc" valign="top" height="100%">
<font size="-1" face="Arial">Welcome to our mobile Sports Extra Web site.
Check here for up-to-the-minute sports news as it happens!</font><br>
</td></tr>
<tr><td bgcolor="#003366" height="4"></td></tr>
</table>
</form></body></html>
















Important

When introducing device-specific markup into the content sent to the client, it's essential that you have a clear understanding of the markup language the client requires and that you study the structure of the markup that the ASP.NET mobile controls generate. You'll need to have access to tools that allow you to examine the source markup that the device receives. With HTML, this is easy—test with Internet Explorer, and click View and then Source to examine the markup. For WML testing, you must have access to a device emulator that offers the facility to view the source markup. Emulators from Nokia, Openwave, Yospace, and others offer this facility. Refer to Chapter 16 for details of available emulators and how to acquire them.


Using <ScriptTemplate>


This template allows you to insert markup directly after the <head> tag in HTML forms or after the opening <card> tag of a WML deck. Possible uses for this template are to add JavaScript functions defined within <script>... </script> tags in an HTML page, define <do> actions on a WML card, or take advantage of features such as the WML <timer> tag. The <ScriptTemplate> is ignored for XHTML clients.

Listing 9-6 shows an example application that inserts WML markup using the WML <timer> tag to display a splash screen graphic for 5 seconds, before the application continues. On non-WML clients, only the text enclosed in the Form control is displayed.

Listing 9-6: Source file ScriptTemplateExample.aspx






<%@ Page language="c#" Inherits="System.Web.UI.MobileControls.MobilePage" 
AutoEventWireup="false" %>
<%@ Register TagPrefix="mobile" Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<mobile:Form id="Form1" runat="server">
This form contains a ScriptTemplate, which is
used to display a splash screen on WML clients.
<mobile:DeviceSpecific id="DeviceSpecific1" runat="server">
<Choice Filter="isWML11">
<ScriptTemplate>
<onevent type="onenterforward">
<go href="#splash"/>
</onevent>
</card>
<card id="splash" ontimer="#MITcard">
<timer value="50"/>
<p align="center">
<big>Welcome</big>
<br/>
<img src="welcome.wbmp"
align="middle"/>
</p>
</card>
<card id="MITcard">
</ScriptTemplate>
</Choice>
</mobile:DeviceSpecific>
</mobile:Form>











This application requires a Web.config file with the isWML11 device filter defined in it (included as standard in mobile applications created in Visual Studio .NET). If this application didn't contain the <ScriptTemplate> element, the WML that the client receives is as shown in Listing 9-7.

Listing 9-7: WML sent to the client if no <ScriptTemplate> is defined






<?xml version='1.0'?>
<!DOCTYPE wml PUBLIC '-//WAPFORUM//DTD WML 1.1//EN'
'http://www.wapforum.org/DTD/wml_1.1.xml'>
<wml>
<head>
<meta http-equiv="Cache-Control" content="max-age=0" />
</head>
<card>
<p>
This form contains a ScriptTemplate, which is
used to display a splash screen on WML clients.
</p>
</card>
</wml>











The application in Listing 9-6 inserts the contents of the <ScriptTemplate> element after the first <card> tag, resulting in the WML shown in Listing 9-8. The markup inserted by the <ScriptTemplate> is shown italicized.

Listing 9-8: WML sent to the client with the contents of the <ScriptTemplate> element inserted






<?xml version='1.0'?>
<!DOCTYPE wml PUBLIC '-//WAPFORUM//DTD WML 1.1//EN'
'http://www.wapforum.org/DTD/wml_1.1.xml'>
<wml>
<head>
<meta http-equiv="Cache-Control" content="max-age=0" />
</head>
<card>
<onevent type="onenterforward">
<go href="#splash"/>
</onevent>
</card>
<card id="splash" ontimer="#MITcard">
<timer value="50"/>
<p align="center">
<big>Welcome</big>
<br/>
<img src="welcome.wbmp" align="middle"/>
</p>
</card>
<card id="MITcard">
<p>
This form contains a ScriptTemplate, which is
used to display a splash screen on WML clients.
</p>
</card>
</wml>












Using the Panel Control's <ContentTemplate> Element


You can use the Panel control template to insert arbitrary blocks of markup into an application. You insert arbitrary markup into a page by using the <HeaderTemplate>, <ScriptTemplate>, and <FooterTemplate> elements of the Form control. However, the Panel control's <ContentTemplate> element completely replaces any other controls or content that you might have defined in the Panel control.

On HTML browsers, the markup you specify in a <ContentTemplate> element is inserted at whatever point you position your Panel control. For a Form control containing only a single Panel control, the contents of the <ContentTemplate> element will be inserted like this:

<body>
<form…>
<!--Markup supplied in a ContentTemplate goes here-->
</form>
</body>

If you use the Panel control template to insert markup for WML browsers, the markup will be inserted this way:

<wml>
<card id=…>
<p>
<!--Markup supplied in a ContentTemplate goes here-->
</p>
</card>
</wml>

Listings 9-9 and 9-10 depict a simple currency converter. For this example to work, you must place the WMLScript file currency.wmls into your application directory. This file is included in the companion material on the book's Web site, in the CurrencyConverter sample directory. You must also configure Internet Information Services (IIS) to serve WMLScript files, as will be described a little later. This example illustrates how you can call a function defined in WMLScript from within a <ContentTemplate> element, which will be rendered only on WML version 1.1 browsers.

Listing 9-9: Source file CurrencyConverter.aspx






<%@ Page language="c#" CodeBehind="CurrencyConverter.aspx.cs" 
Inherits="MSPress.MobWeb.CurrencyConverter.MyWebForm"
AutoEventWireup="true" %>
<%@ Register TagPrefix="mobile"
Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<mobile:form id="Form1" title="Currency" runat="server">
Enter Amount in cents/pence:
<mobile:TextBox id="TextBox1" runat="server" Numeric="True">
</mobile:TextBox>
<mobile:Label runat="server">From:</mobile:Label>
<mobile:SelectionList id="SelectionList1" runat="server">
<Item Value="EUR" Text="Euro"></Item>
<Item Value="GBP" Text="Sterling"></Item>
<Item Value="USD" Text="Dollar"></Item>
</mobile:SelectionList>
<mobile:Label runat="server">To:</mobile:Label>
<mobile:SelectionList id="SelectionList2" runat="server">
<Item Value="EUR" Text="Euro"></Item>
<Item Value="GBP" Text="Sterling"></Item>
<Item Value="USD" Text="Dollar"></Item>
</mobile:SelectionList>
<mobile:Panel id="Panel1" runat="server">
<mobile:DeviceSpecific id="DeviceSpecific1" runat="server">
<Choice Filter="isWML11">
<ContentTemplate>
<do type="accept" label="Convert">
<go href="currency.wmls#convert('$SelectionList1',
'$SelectionList2','$TextBox1')" />
</do>
</ContentTemplate>
</Choice>
</mobile:DeviceSpecific>
</mobile:Panel>
</mobile:Form>
<mobile:Form id="Form2" runat="server">
<mobile:Label runat="server">
I'm sorry. This function is not yet available on your device.
</mobile:Label>
</mobile:Form>











Listing 9-10: Code-behind file CurrencyConverter.aspx.cs






using System;
using System.Web.Mobile;
using System.Web.UI.MobileControls;
Namespace MSPress.MobWeb.CurrencyConverter
{
public class MyWebForm : System.Web.UI.MobileControls.MobilePage
{
protected System.Web.UI.MobileControls.Form Form2;
protected void Page_Load(Object sender, EventArgs e)
{
MobileCapabilities cap = (MobileCapabilities)Request.Browser;
if (!cap.HasCapability("isWML11", null))
{
//Not a WML device. We do not support this yet.
ActiveForm = Form2;
}
}
}
}


















Enabling WMLScript in IIS


To execute a sample like the currency converter in Listings 9-9 and 9-10, you must enable IIS to serve WMLScript files. The same is true if you want to serve static WML files that have a .wml file extension (as distinct from WML created by an ASP.NET mobile controls application). To do so, follow these steps:



In Control Panel, double-click Administrative Tools, and open Internet Information Services, or open Internet Information Manager if you're running Microsoft Windows 2000.



Expand the tree view, right-click on Default Web Site, and then click Properties. (In Windows 2000, you right-click on the Web Server item to get to Properties.)



On the HTTP Headers tab, click the File Types button in the MIME Map section. (You'll find this button labeled Edit on the Internet Information Services tab in Windows 2000.)



Click New Type and type .wmls for the Associated extension and text/vnd.wap.wmlscript for the Content type (MIME). To serve static WML files, use the extension .wml and the MIME type text/vnd.wap.wml.



For this change to take effect, you must stop the IIS service and restart it again.











The CurrencyConverter application pulls together some of the features we've described in this chapter. In the Page_Load method, the HasCapability method of the MobileCapabilities object determines whether the requesting device supports WML version 1.1. If it doesn't, a form displaying an apology appears.

The Form1 form uses standard mobile controls to accept input from the user. Then <ContentTemplate> inserts WML code for a <do type="accept"> command, which is rendered as a softkey or another link with the legend Convert. When selected, the softkey calls the convert function in the WMLScript file named currency.wmls, which it fetches from the Web server. The convert function takes arguments that are the values the user entered (the variables $SelectionList1, $SelectionList2, and $TextBox1). Figure 9-8 shows the resulting WML markup.


Figure 9-8: WML markup created for the CurrencyConverter application

The WML client browser fetches the WMLScript module currency.wmls (not shown) from the Web server. The convert function contained within this script module calculates the result and displays it using a WMLScript Dialog function.

Using <ContentTemplate> to Run JavaScript on the Client


Certain HTML browsers, such as Pocket Internet Explorer on a Pocket PC, support the running of JavaScript functions embedded in the HTML page sent to the client. You can use the <ContentTemplate> to send JavaScript for execution on a client that can handle it.

In Listing 9-11 below, the contents of the <ContentTemplate> is a JavaScript function that executes when the Window onLoad event happens—which is when the Web page sent to the browser is loaded for display. This function calls the Window.alert JavaScript function to display a pop-up message window, and then sets input focus to TextBox1.

Listing 9-11: Source file JavaScriptExample.aspx






<%@ Page language="c#" 
Inherits="System.Web.UI.MobileControls.MobilePage" %>
<%@ Register TagPrefix="mobile"
Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<mobile:Form id="Form1" runat="server">
<mobile:Panel id="Panel1" runat="server">
<mobile:DeviceSpecific id="DeviceSpecific1" Runat="server">
<Choice Filter="supportsJavaScript">
<contenttemplate>
<Script for="window" event="onload"
language="jscript">
window.alert("Hello from JavaScript");
window.Form1.TextBox1.focus();
</Script>
</contenttemplate>
</Choice>
</mobile:DeviceSpecific>
</mobile:Panel>
<mobile:TextBox id="TextBox1" runat="server" text="1st TextBox"/>
<mobile:TextBox id="TextBox2" runat="server" text="2nd TextBox"/>
</mobile:Form>












Working with Controls in Form and Panel Templates


You're used to setting properties of controls on a mobile Web Forms page from within code. However, if you've placed a control in a template and you try to set a property of that control in code using its control ID to identify it, as you might normally do, a run-time error occurs.

For example, assume you have this simple template applied to a Form control:

<mobile:Form id="Form1" runat="server" >
<mobile:DeviceSpecific id="DeviceSpecific1" runat="server">
<Choice>
<HeaderTemplate>
<mobile:Label runat="server" id="Label1">
This appears at the head of each page
</mobile:Label>
</HeaderTemplate>
</Choice>
</mobile:DeviceSpecific>
</mobile:Form>

You might expect to be able to set properties of the Label control in code like so:

Label1.Text = "This label's Text property is set in code";

In fact, this returns a run-time error, stating that Label1 is a null object.

Introduction to the TemplateContainer Object


This error is due to the way that the contents of templates are instantiated. Every control that supports templates has one or more child controls that are either System.Web.UI.MobileControls.TemplateContainer objects or objects descended from the TemplateContainer class. When you define a template, the contents of that template are instantiated as child controls of the TemplateContainer object, ASP.NET and mobile controls are instantiated as themselves (like the Label control in the example above), and any literal text (for example, native markup code) is instantiated as System.Web.UI.MobileControls.LiteralText objects. The controls defined in templates are not direct children of a standard container control like Form or Panel but are instead hidden down the control tree, so to address them in code you must use a different technique.

The Form control has Footer, Header, and Script properties that expose the TemplateContainer objects for the <FooterTemplate>, <HeaderTemplate>, and <ScriptTemplate> elements. The Panel control has a Content property that exposes the TemplateContainer object for the <ContentTemplate> element. You can use the FindControl method of System.Web.UI.Control (the parent class of MobileControl) to locate the specific child controls of one of these TemplateContainer objects.

Using FindControl to Locate Controls in the Control Tree


You use the FindControl method with any control that is a Naming Container. Naming Container objects are those that implement the INamingContainer interface, and they guarantee that any child controls they contain have a unique name within the mobile Web Forms page. TemplateContainer objects are Naming Containers. The Form and Panel controls expose the TemplateContainer object for a particular template through special properties: Footer, Header, Script, or Content. To get a reference to any control inside a template, you get a reference to the TemplateContainer object by getting the appropriate property of the Form and Template and then call the TemplateContainer object's FindControl method, passing the ID of the child control.

In Listing 9-12, the Form control's <HeaderTemplate> element contains a Label control with the ID Label2. In the Page_Load method in Listing 9-12, the Header property of Form1 returns the TemplateContainer object for the <HeaderTemplate> element. Then the FindControl method locates Label2 so that its properties can be set.

Listing 9-12: Source file TemplateControlsInCodeExample.aspx






<%@ Register TagPrefix="mobile" 
Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<%@ Page language="c#"
Codebehind="TemplateControlsInCodeExample.aspx.cs"
Inherits="MSPress.MobWeb.TemplateControlsInCode.MobileWebForm1"
AutoEventWireup="true" %>
<mobile:Form id="Form1" runat="server">
<mobile:Label id="Label1" runat="server">
This control is in the Form
</mobile:Label>
<mobile:DeviceSpecific id="DeviceSpecific1" runat="server">
<Choice>
<HeaderTemplate>
<mobile:Label id="Label2" runat="server">
This control is in the template
</mobile:Label>
</HeaderTemplate>
</Choice>
</mobile:DeviceSpecific>
</mobile:Form>











Listing 9-13: Code-behind file TemplateControlsInCodeExample.aspx.cs






using System;
using System.Web.UI;
using System.Web.UI.MobileControls;
namespace MSPress.MobWeb.TemplateControlsInCode
{
public class MobileWebForm1 : System.Web.UI.MobileControls.MobilePage
{
protected System.Web.UI.MobileControls.Label Label1;
protected System.Web.UI.MobileControls.DeviceSpecific DeviceSpecific1;
protected System.Web.UI.MobileControls.Form Form1;
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
}
private void Page_Load(object sender, System.EventArgs e)
{
// The 'header' property exposes the Header template container
Label LabelInTemplate = this.Form1.Header.FindControl("Label2")
as Label;
//Set property of the label in the template
LabelInTemplate.Text = "Text reset in Code";
}
}












Defining Templates Using Visual Studio .NET Tools


The Mobile Internet Designer provides graphical tools for defining templates that work in tandem with the tools for defining device filters and DeviceSpecific/Choice constructs. You can use these graphical tools as an alternative to editing the source files directly. These tools make it easy to create templates. However, you must perform the following six tasks in sequence:



Define device filters for your application.



Enable DeviceSpecific/Choice constructs on the desired controls.



Apply the device filters for templating.



Select each applied device filter, one at a time, to edit the templates.



Edit the templates.



Finish editing.



Let's take a closer look at each of these tasks.

Defining Device Filters for Your Application


You must define all templates within the context of a DeviceSpecific/Choice construct, even if this consists of only a single default <Choice> element that applies to all devices. Therefore, you must first define device filters for your application, as described earlier in this chapter, in the section "Defining Device Filters Using Visual Studio .NET Tools." If you need to add device filters later, you can access the Device Filter Editor from either the Applied Device Filters dialog box, or the Templating Options dialog box, which we will discuss shortly.

Enabling DeviceSpecific/Choice Constructs on the Desired Controls


How you apply templates depends on whether you're using the Form and Panel controls or the List and ObjectList controls. To apply templates to Form and Panel controls, drag a DeviceSpecific control from the Toolbox onto the Form or Panel control. The Mobile Internet Designer will allow you to drag only one DeviceSpecific control onto a Form or Panel control. Like all other controls contained within the Form or Panel container controls, the List and ObjectList controls already support DeviceSpecific/Choice constructs. Therefore, you don't have to drag this capability onto those controls, as you do with the Form and Panel controls.

Applying Device Filters for Templating


As we described earlier in this chapter, in the section "Defining Device Filters using Visual Studio .NET Tools" the (Applied Device Filters) option within the Properties window provides access to the Device Filters Editor, and the (Property Overrides) option allows you to define property overrides using device filters that you've applied to the control.

You must define which device filters you want to use with your templates. In Design view, select the control for which you want to define templates by clicking it. At the bottom of the Properties window, you'll see a link to Templating Options. The same option is available from the context menu, which you can access by right-clicking the control, as Figure 9-9 shows.


Figure 9-9: Applying device filters to templated controls through the Templating Options link

By selecting either the menu option, or the Properties window link, the Templating Options dialog box will appear. Initially, the Applied Device Filter drop-down list contains only the (None) option, indicating that you haven't yet applied any device filters to this control for templating, as Figure 9-10 shows. Be aware that if you've already applied device filters to create property overrides, by definition these filters will apply to templating as well. You'll see these device filters in the Applied Device Filter drop-down list.


Figure 9-10: The Templating Options dialog box

Click the Edit button to access the Applied Device Filters dialog box. Select the device filters that you want to use with this control, just as you did for the property overrides. Remember, each device filter that you apply to this control has its own set of templates, and you need to edit the templates separately for each filter. You don't have to define all the available templates. Default control rendering applies to any function that a template doesn't override.

Selecting Each Applied Device Filter to Edit the Templates


After you've applied device filters to the control, select which filter to edit from the Applied Device Filter list. The Markup Schema option indicates which markup schema to apply to the content you enter into the template. This setting has no effect at run time; its only use is to provide assistance in the form of Microsoft IntelliSense and auto-completion while you edit within the HTML view of the Mobile Internet Designer. After making your selection for template editing, click Close.

Each time you want to switch to a different applied device filter to edit its associated templates, you must select that filter from the Templating Options dialog box. A quicker way to select an applied device filter for template editing is to choose it from the Template Device Filter dialog box in the Properties window.

Editing the Templates


Right-click the templated control once more, and click Edit Templates. Then click on the template you want to edit. The Mobile Internet Designer now presents a design area within each selected template. Figure 9-11 shows how such a design area looks.


Figure 9-11: Editing in the design area in Mobile Internet Designer

You can type literal text into this design area or drag controls onto it from the Toolbox. When typing device-specific markup, we advise that you switch to HTML view to benefit from IntelliSense editing support.

Finishing Editing


When your changes are complete, right-click the control again and select End Template Editing. Note that switching between Design view and HTML view also terminates editing.


Defining Templates Within Style Sheets


The facilities for defining styles within style sheets and customizing the presentation of the Form, Panel, List, and ObjectList controls using templates enable extensive customization of your applications. Nonetheless, getting the presentation exactly as you want it often requires a great deal of time and effort. Once you've defined a presentation style you're happy with, you'll undoubtedly want to apply it to other projects.

As we described in Chapter 8, in the section "Programming Styles and Style Sheets," you can store styles in style sheets to apply them to multiple controls. You can also use external style sheets to encapsulate styles to apply to multiple projects. This encapsulation also extends to template sets. By placing styles and template sets under a named style within a style sheet, you can apply styles and templating options to different controls in multiple projects, just by setting the controls' StyleReference property to the appropriate external style.

Chapter 10; however, the techniques demonstrated in the sample apply just as well to the templates of the Form and Panel controls. In this sample, the template set resides in the style named MyListStyle within the StyleSheet control. The List control in Form1 accesses the template set by setting the StyleReference property to MyListStyle.

Listing 9-14: Source file TemplatesInStyleSheetsExample.aspx






<%@ Page Language="c#" Inherits=
"MSPress.MobWeb.TemplatesInStylesheetsExample.ExampleWebForm"
CodeBehind="TemplatesInStylesheetsExample.aspx.cs"%>
<%@ Register TagPrefix="mobile"
Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<mobile:Stylesheet runat="server">
<Style Name="MyListStyle" Font-Name="Arial">
<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>
</Style>
</mobile:Stylesheet>
<mobile:Form runat="server" id="Form1">
<mobile:Label runat="server" StyleReference="title">
Season 2003 results
</mobile:Label>
<mobile:List id="List1" runat="server"
StyleReference="MyListStyle"
OnItemCommand="ClickTeamSelection"
DataTextField="TeamName"
DataValueField="Stats">
</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 9-15: Code-behind file TemplatesInStylesheetsExample.aspx.cs






using System;
using System.Collections;
using System.Web.UI.MobileControls;
namespace MSPress.MobWeb.TemplatesInStylesheetsExample
{
public class ExampleWebForm : System.Web.UI.MobileControls.Mobile Page
{
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 System.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; }
}
}
}











You can encapsulate Form and Panel control templates in style sheets in a similar way. Encapsulating styles and templates this way and placing them within an external style sheet allows you to reuse the styles you've developed in multiple applications. Thus, you can more easily apply a consistent appearance and shorten the development time needed to produce visually outstanding applications.

/ 145