Building Controls by Inheritance
In this scenario, an existing mobile control provides most of the functionality you need. However, you can extend that control to provide additional properties and events. Or you can make the control specialized, such as a List control that's designed to read news reports from a database, display the headlines as a list of links, and display the news text when the user selects a headline from the display list.As a simple example, consider a specialized List control that lists data from an XML file. To build this control, you need to create a new control that inherits and extends the standard List control by performing the following steps:
Create a new property named XMLsource that specifies the path and file name of the data source.
Use the DataMember property inherited from the base List class to specify the XML node to read from the source. Use the DataTextField and DataValueField properties to specify the attributes to extract from and insert into the list.
Override the OnLoad method so that it uses the System.Xml.XmlTextReader class from the Microsoft .NET Framework to parse the XML input and build the list.
To build a custom mobile control in Microsoft Visual Studio .NET, select the Web Control Library project template in the New Project dialog box. After Visual Studio .NET creates the project, click the Project menu, then click Add Reference, and add the Mobile Internet Controls Runtime to your project—the assembly file name you need to reference is named System.Web.Mobile.dll. This particular example requires the .NET Framework classes that manipulate XML resources. Because these classes reside in the System.Xml.dll assembly, you must add a reference to that assembly as well.The code for this control is quite simple, as Listing 21-1 shows. The control overrides the OnLoad method of the parent List control and uses the XMLTextReader object to parse the input file that you specify through the XMLSource property. The runtime creates a MobileListItem object for each element in the XML source that has the same name as the DataMember property. The code sets the Text property of the MobileListItem object to the value of the attribute whose name matches the DataTextField property and sets the Value property to the value of the attribute whose name matches the DataValueField property. We've kept the error handling very rudimentary in this example.
Listing 21-1: Source file CustomMobileControlLibrary.cs implements the custom xmlList control
using System;
using System.Xml;
using System.Web.UI.MobileControls;
namespace MSPress.MobWeb.CustomControls
{
public class xmlList : System.Web.UI.MobileControls.List
{
private String _xmlSource;
/// <summary>
/// Get and set the file containing the XML data to be parsed.
/// </summary>
public String XMLsource
{
get
{
return _xmlSource;
}
set
{
_xmlSource = value;
}
}
protected override void OnLoad(EventArgs e)
{
if (!Page.IsPostBack)
{
base.OnLoad(e);
// Get the path to the source on the local Web server.
String strFullPath = Page.Server.MapPath(_xmlSource);
XmlTextReader xmlreader = null;
try
{
xmlreader = new XmlTextReader(strFullPath);
while (xmlreader.Read())
{
if (xmlreader.NodeType == XmlNodeType.Element)
{
if (xmlreader.Name == this.DataMember)
{
MobileListItem item =
new MobileListItem();
while (xmlreader.MoveToNextAttribute())
{
if (xmlreader.LocalName ==
this.DataTextField)
{
item.Text = xmlreader.Value;
}
if (xmlreader.LocalName ==
this.DataValueField)
{
item.Value = xmlreader.Value;
}
}
Items.Add(item);
}
}
}
}
catch
{
if (xmlreader != null) xmlreader.Close();
}
}
}
}
}
For example, suppose that the XML source file contains the data shown in Listing 21-2 and that you set the DataMember, DataTextField, and DataValueField properties of an xmlList control to Team, TeamName, and Coach, respectively. The control will then display a list of the values of the TeamName attribute and set the hidden list item value to the value of the Coach attribute.Listing 21-2: Contents of the TeamData.xml file, which is XML-encoded data used as the data source for the xmlList custom control
<?xml version="1.0"?>
<Premiership>
<Team TeamName="Dunes"
Played="3"
Won="3"
Drawn="0"
Lost="0"
Points="9"
Coach="Robert Brown"/>
<Team TeamName="Toffees"
Played="3"
Won="2"
Drawn="1"
Lost="0"
Points="7"
Coach="Jeff Price"/>
<Team TeamName="Phoenix"
Played="3"
Won="2"
Drawn="1"
Lost="0"
Points="7"
Coach="Robert O'Hara"/>
</Premiership>
The xmlList control shown in Chapter 20, in Listing 20-2, where the set accessor for the SelectedDate property in the user control example included validation logic that verified that the date was within permissible boundaries.
Using a Compiled Custom Control
Any controls you build in code compile into an assembly with a .dll file extension. To use an assembly containing custom controls, you must add a reference to the assembly in your Visual Studio .NET project, just as you would with any other .NET assembly. This makes a private copy of the referenced assembly in the application's \bin directory. Then you add a Register directive to the head of the mobile Web Forms page to associate a TagPrefix with the classes in the assembly that contains the custom controls, just as you would to associate the TagPrefix "mobile" with the ASP.NET Mobile Controls in their assembly. Here's the syntax:
<%@ Page language="c#"
Inherits="System.Web.UI.MobileControls.MobilePage"%>
<%@ Register TagPrefix="mobile"
Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<%@ Register TagPrefix="CMcustom"
Namespace="MSPress.MobWeb.CustomControls"
Assembly="CustomMobileControlLibrary" %>
To use the control, reference it in the ASP.NET server control syntax by using the declared TagPrefix and the control's class name:
<CMcustom:xmlList id="lstTeamList" runat="server"
DataValueField="Coach" DataTextField="TeamName"
DataMember="Team" xmlSource="TeamData.xml" >
</CMcustom:xmlList>
In every way, this particular control remains a List control—but it's a List control with particular capabilities that you've programmed. For example, you can still implement an OnItemCommand event handler to execute when the user selects an item from this List control. And, unless you override them, this List control still possesses the properties of its parent List control.Listing 21-3 provides a full example of using the xmlList control. This example requires you to place the TeamData.xml XML source file in the application directory.Listing 21-3: Source file Default.aspx demonstrates the use of the xmlList control
<%@ Page language="c#"
Inherits="System.Web.UI.MobileControls.MobilePage"%>
<%@ Register TagPrefix="mobile"
Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<%@ Register TagPrefix="CMcustom"
Namespace="MSPress.MobWeb.CustomControls"
Assembly="CustomMobileControlLibrary" %>
<head>
<script runat="server" language="C#">
public void SelectItem(
Object source,
ListCommandEventArgs args)
{
// Display the second page.
this.ActiveForm = Form2;
Label1.Text = "You selected: " + args.ListItem.Text
+ ":" + args.ListItem.Value;
}
</script>
</head>
<body>
<mobile:Form id="Form1" runat="server">
<CMcustom:xmlList id="lstTeamList" runat="server"
DataValueField="Coach" DataTextField="TeamName"
DataMember="Team" xmlSource="TeamData.xml"
OnItemCommand="SelectItem">
</CMcustom:xmlList>
</mobile:Form>
<mobile:Form id="Form2" runat="server">
<mobile:Label id="Label1" runat="server"></mobile:Label>
</mobile:Form>
</body>
When the user selects an item in the List control, the second form is displayed, as shown in Figure 21-2.
Figure 21-2: Using the XML-parsing custom List control in Pocket Internet Explorer