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

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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






User Control Example


You've already created a simple user control that displays only a Label control. In this section, you'll create a more complex example. The Calendar control is ideal for applications in which the user needs to select a date. However, this control provides a rich user interface that takes up a lot of space on a Pocket PC and can span many screens on a mobile phone.

To see an example of a user control, let's build a more compact date selector that is rendered as three drop-down lists on an HTML browser and as a single input box on a WML browser. We'll call this control the Short Date control. Short Date allows a user to select a date between 01-Jan-2003 and 31-Dec-2010. You can build the bare bones of this control by using server control tags, as Listing 20-1 shows.

Listing 20-1: Source file ShortDateControl.ascx






<%@ Control CodeBehind="ShortDateControl.ascx.cs" 
Inherits="MSPress.MobWeb.UserControlExample.ShortDateControl"
Language="c#" AutoEventWireup="false" %>
<%@ Register TagPrefix="mobile"
Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<mobile:Panel id="Panel1" runat="server">
<mobile:DeviceSpecific id="DeviceSpecific1" runat="server">
<Choice Filter="isWML11">
<ContentTemplate>
<mobile:Label id="Label1" runat="server">
Enter date (MMDDYY):</mobile:Label>
<mobile:TextBox id="TextBox1" runat="server"
numeric="true" Text="010103" MaxLength="6"
wmlFormat="NN\/NN\/NN">
</mobile:TextBox>
</ContentTemplate>
</Choice>
<Choice Filter="isHTML32">
<ContentTemplate>
<table>
<tr>
<td>
<mobile:Label id="Label2" runat="server"
BreakAfter="false">
Day:</mobile:Label>
</td>
<td align="right">
<mobile:SelectionList id="SelectionList1"
runat="server" BreakAfter="false">
<Item Text="01" />


Intervening items not shown


<Item Text="31" />
</mobile:SelectionList>
</td>
</tr>
<tr>
<td>
<mobile:Label id="Label3" runat="server"
BreakAfter="false">
Month:</mobile:Label>
</td>
<td align="right">
<mobile:SelectionList id="SelectionList2"
runat="server" BreakAfter="false">
<Item Text="Jan" Value="01" />


Intervening items not shown


<Item Text="Dec" Value="12" />
</mobile:SelectionList>
</td>
</tr>
<tr>
<td>
<mobile:Label id="Label4" runat="server"
BreakAfter="false">
Year:</mobile:Label>
</td>
<td align="right">
<mobile:SelectionList id="SelectionList3"
runat="server" BreakAfter="false">
<Item Text="2003" />


Intervening items not shown


<Item Text="2010" />
</mobile:SelectionList>
</td>
</tr>
</table>
</ContentTemplate>
</Choice>
</mobile:DeviceSpecific>
</mobile:Panel>












When you include the Short Date control on a Form control, the DeviceSpecific/Choice construct inside Panel1 tests whether isWML11 is true. If it is, the device is a Wireless Application Protocol (WAP) handset, and the control is displayed as a text box that accepts a six-digit number. On HTML devices, this control outputs a <table> element containing three drop-down lists with prompt labels. However, to be really useful, this control needs to have additional functionality defined in its code-behind module. (We'll describe how to add this functionality in the following sections.) As it stands, the control displays the default date Jan 1, 2003. The user can enter a different date, but there's no way to access his or her selection.

Note that this user control has an external dependency. You must define the following isWML11 and isHTML capability evaluators in the Web.config file of any application in which you want to use this control.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<deviceFilters>
<filter name="isHTML32" compare="PreferredRenderingType"
argument="html32" />
<filter name="isWML11" compare="PreferredRenderingType"
argument="wml11" />
</deviceFilters>
</system.web>
</configuration>

If you use Visual Studio .NET to create your mobile Web applications, the runtime will include isWML11 and isHTML in Web.config by default. See Chapter 9 for more information about capability evaluators.


Implementing Properties in a User Control


To make the Short Date user control useful, you must give it a public property through which you can set the starting date and can retrieve the user's selection after the control executes. You implement this functionality in the code-behind module. You add a private data member to the class of type System.DateTime, named _currentdate. A public property named SelectedDate allows clients to get or set the control's _currentdate member. The set accessor for SelectedDate validates the date values passed in, ensuring that they're within range. Finally, in the class constructor, the application initializes _currentdate to today's date and defines the minimum and maximum dates allowed in the control. The application then uses the minimum and maximum dates in the set accessor's validation code. Chapter 4 for more information about custom attributes and the wmlFormat attribute of the TextBox control.)

Listing 20-2: Code-behind module ShortDateControl.ascx.cs






using System;
using System.Web;
using System.Web.Mobile;
using System.Web.UI.MobileControls;
namespace MSPress.MobWeb.UserControlExample
{
/// <summary>
/// Compact date selector
/// </summary>
public abstract class ShortDateControl :
System.Web.UI.MobileControls.MobileUserControl
{
protected System.Web.UI.MobileControls.Panel Panel1;
private DateTime _currentdate;
private DateTime _minDate;
private DateTime _maxDate;
/// <summary>
/// Gets and sets the date displayed in System.DateTime format.
/// </summary>
public System.DateTime SelectedDate
{
get
{
return _currentdate;
}
set
{
if ((value < _minDate) || (value > _maxDate))
{
// Invalid date
throw(new ArgumentOutOfRangeException
("SelectedDate",
value.ToString("d-MMM-yyy"),
"Date out of supported range 01-Jan-2003 to 31-Dec-2010"
));
}
_currentdate = value;
}
}
public ShortDateControl()
{
_currentdate = DateTime.Now;
_minDate = new DateTime(2003,1,1);
_maxDate = new DateTime(2010,12,31);
}
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)
{
// Allow custom attributes so we can use the wmlFormat attribute.
((MobilePage)Page).AllowCustomAttributes = true;
}
}
}












Displaying the Properties of the User Control


The SelectedDate property defines the currently selected date of the user control. However, you must set the child controls in this user control to display that date. This seems like a simple task; just set the Text property of TextBox1 if the client is a WML client, or set the SelectedIndex property of each of the SelectionList controls if it's an HTML client. However, this relatively simple task is complicated in this particular user control by the fact that it uses a <ContentTemplate> element within a Panel control. Thus, the controls you need to set aren't top-level controls; instead, they are child controls inside a TemplateContainer control, which is itself a child of Panel1.

As described in Chapter 9, you must use the FindControl method of System.Web.UI.Control to search through the control tree in the user control to find controls that have been instantiated as children of a template. The Content property of the Panel control exposes the TemplateContainer that contains the controls inside the template. Call the FindControl method of this TemplateContainer, passing the ID of the child controls to locate them.





Tip

If you're finding it difficult to understand the control hierarchy in a mobile Web Forms page, turn on the Trace facility 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 with naming contexts.


For example, to find the SelectionList control with an ID of SelectionList1, you use the following code:

protected System.Web.UI.MobileControls.Panel Panel1;
private System.Web.UI.MobileControls.SelectionList SelDay;
private void Page_Load(object sender, System.EventArgs e)
{
// Find the SelectionList control in the template
SelDay = Panel1.Content.FindControl("SelectionList1") as SelectionList;



Notice that the protected class member

Panel1 is a reference to the top-level control

Panel1 , which is declared in the .ascx file shown in Table 21-1, in Chapter 21, for more details on the life cycle of a control.) The PreRender event handler is wired up by the addition to the InitializeComponent method.

Listing 20-3: Listing of ShortDateControl.ascx.cs, showing enhancements required to set properties of the visual elements so that they display the currently selected date






public abstract class ShortDateControl : 
System.Web.UI.MobileControls.MobileUserControl
{
protected System.Web.UI.MobileControls.Panel Panel1;
private System.Web.UI.MobileControls.SelectionList SelDay;
private System.Web.UI.MobileControls.SelectionList SelMonth;
private System.Web.UI.MobileControls.SelectionList SelYear;
private System.Web.UI.MobileControls.TextBox WMLDate;
private DateTime _currentdate;
private DateTime _minDate;
private DateTime _maxDate;
/// <summary>
/// Gets and sets the date displayed in System.DateTime format.
/// </summary>
public System.DateTime SelectedDate
{
get
{
return _currentdate;
}
set
{
if ((value < _minDate) || (value > _maxDate))
{
// Invalid date
throw(new ArgumentOutOfRangeException
("SelectedDate",
value.ToString("d-MMM-yyy"),
"Date out of supported range 01-Jan-2003 to 31-Dec-2010"
));
}
_currentdate = value;
}
}
public ShortDateControl()
{
_currentdate = DateTime.Now;
_minDate = new DateTime(2003,1,1);
_maxDate = new DateTime(2010,12,31);
}
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
this.PreRender += new System.EventHandler(this.Page_PreRender);
}
private void Page_Load (object sender, System.EventArgs e)
{
// Allow custom attributes so we can use the wmlFormat attribute.
((MobilePage) Page).AllowCustomAttributes = true;
Panel1.EnsureTemplatedUI();
if (((MobileCapabilities)(Request.Browser))
.HasCapability("isWML11","))
{
// Set for WML
WMLDate = Panel1.Content.FindControl("TextBox1") as TextBox;
}
else
{
// Set for HTML and cHTML
SelDay = Panel1.Content.FindControl("SelectionList1")
as SelectionList;
SelMonth = Panel1.Content.FindControl("SelectionList2")
as SelectionList;
SelYear = Panel1.Content.FindControl("SelectionList3")
as SelectionList;
}
}
private void Page_PreRender(object sender, System.EventArgs e)
{
if (((MobileCapabilities)(Request.Browser))
.HasCapability("isWML11","))
{
// Set display properties for the WML version
if (WMLDate != null)
WMLDate.Text = _currentdate.ToString("MM/dd/yy");
}
else
{
// Set for HTML and cHTML
if (SelDay != null)
SelDay.SelectedIndex = _currentdate.Day - 1;
if (SelMonth != null)
SelMonth.SelectedIndex = _currentdate.Month - 1;
if (SelYear != null)
SelYear.SelectedIndex = _currentdate.Year - 2003;
}
}
}
}












Responding to Events in a User Control


With this code, you can use the Short Date user control in a mobile Web Forms page, and you can initialize the control to a particular date by using the SelectedDate property. All that remains is to trap the user's input so that your SelectedDate property can discover which date the user selected. You achieve this the same way as you do in a mobile Web Forms page.

You define an event handler method for the SelectedIndexChanged event for each of the three SelectionList controls the client uses to enter the day, month, and year. However, you define an event handler for the TextChanged event for the text box used for WML clients, as Listing 20-4 shows.

Listing 20-4: Modified Page_Load method of ShortDateControl.ascx.cs, showing the declaration of event handlers






private void Page_Load(object sender, System.EventArgs e)
{
// Allow custom attributes so we can use the wmlFormat attribute.
((MobilePage)Page).AllowCustomAttributes = true;
Panel1.EnsureTemplatedUI();
if (((MobileCapabilities)(Request.Browser))
.HasCapability("isWML11","))
{
WMLDate = Panel1.Content.FindControl("TextBox1") as TextBox;
// Set event handler for the WML version
WMLDate.TextChanged +=
new System.EventHandler(this.ChangeWMLDate);
}
else
{
// Set for HTML and cHTML
SelDay = Panel1.Content.FindControl("SelectionList1")
as SelectionList;
SelMonth = Panel1.Content.FindControl("SelectionList2")
as SelectionList;
SelYear = Panel1.Content.FindControl("SelectionList3")
as SelectionList;
SelDay.SelectedIndexChanged +=
new System.EventHandler(this.ChangeDate);
SelMonth.SelectedIndexChanged +=
new System.EventHandler(this.ChangeDate);
SelYear.SelectedIndexChanged +=
new System.EventHandler(this.ChangeDate);
}
}











Listing 20-5 shows the event handler routines that you need to use to save the user action results to the currentdate member variable of the class.

Listing 20-5: Event handlers saving user action results to the class member variable






private void ChangeDate(object sender, System.EventArgs e)
{
SelectedDate = new DateTime(
SelYear.SelectedIndex + 2003,
SelMonth.SelectedIndex + 1,
SelDay.SelectedIndex + 1);
}
private void ChangeWMLDate(object sender, System.EventArgs e)
{
// Date may be in MM/DD/YY format from WML clients
String InputDate = WMLDate.Text.Replace("/", ");
SelectedDate = new DateTime(
int.Parse(InputDate.Substring(4,2)) + 2000,
int.Parse(InputDate.Substring(0,2)),
int.Parse(InputDate.Substring(2,2)));
}











This user control is now functional, but there's still much room for improvement. For example, the control could offer standard style properties, such as ForeColor, BackColor, and Font. You handle these properties by directly setting the corresponding properties of one or more of the child controls in the user control. In this case, doing so is easy. This is because setting the property in the Panel control causes all the child controls to inherit that setting. The following code illustrates this concept:

/// <summary>
/// Gets and sets the date field's ForeColor.
/// </summary>
public System.Drawing.Color ForeColor
{
get
{
return Panel1.ForeColor;
}
set
{
Panel1.ForeColor = value;
}
}

To significantly improve this solution, you could make the control sensitive to the current setting of the enclosing page's Culture property. To do this, you make the format for date input appropriate for the current culture. (See Chapter 14 for a description of the Culture setting and culture-specific formatting.) You can then internationalize the control, which could display a drop-down list and labels in various languages.

You can use the current control in a mobile Web Forms page, as Listing 20-6 demonstrates. This example sets the selected date of the control to March 02, 2004.

Listing 20-6: Default.aspx of sample UserControlExample—mobile Web Forms page that uses the Short Date user control






<%@ Register TagPrefix="mobile" 
Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile" %>
<%@ Page language="c#" Inherits="System.Web.UI.MobileControls.MobilePage" %>
<%@ Register TagPrefix="custom" TagName="ShortDateUC"
Src="ShortDateControl.ascx" %>
<head>
<script runat="server" language="C#">
public void Button_OnClick(Object sender, EventArgs e)
{
Label1.Text = "You selected: "
+ ucShortDate.SelectedDate.ToLongDateString();
this.ActiveForm = Form2;
}
</script>
</head>
<body>
<mobile:form id="Form1" runat="server">
<custom:ShortDateUC id="ucShortDate" runat="server"
SelectedDate="02-Mar-2004" ForeColor="Firebrick">
</custom:ShortDateUC>
<mobile:Command id="Command1" Runat="server"
onclick="Button_OnClick" Text="Next">
</mobile:Command>
</mobile:form>
<mobile:Form ID="Form2" Runat="Server">
<mobile:Label id="Label1" Runat="Server" />
</mobile:Form>
</body>











After the user selects a date and clicks the Next button, the second form displays the new selected date of the user control, as Figure 20-1 shows.


Figure 20-1: Output of the Short Date user control on the Openwave simulator

/ 145