The New Form- and Page-Based Controls in ASP.NET 2.0

In this section we examine the new controls that have been added to ASP.NET 2.0 predominantly to implement single elements such as those used for the individual parts of the UI in a Web page.

The BulletedList Control

The BulletedList control provides an easy route to creating <ol> and <ul> lists in a page. Because it inherits from ListControl , the contents of the list can be created by using child ListItem controls or through data binding. It also adds extra features; for example, you can display each item as a HyperLink or a LinkButton and then handle the OnClick event that the BulletedList control exposes to see which item was clicked.

The style of bullet used in the list is specified as the BulletStyle property, using values from the BulletStyle enumeration. They are pretty much self-explanatory and consist of: Numbered , LowerAlpha , UpperAlpha , LowerRoman , UpperRoman , Disc , Circle , Square , and CustomImage . The default, if not specified, is a decimal numbered list. It is also possible to specify the starting number for the list by setting the FirstBulletNumber property. Listing 12.1 shows the simplest form of a declaration of a BulletedList control, followed by one that specifies a numeric list starting at 4.

Listing 12.1 Using the BulletedList Control
 <asp:BulletedList id="List1" runat="server">   <asp:ListItem runat="server">test1</asp:ListItem>   <asp:ListItem runat="server">test2</asp:ListItem>   <asp:ListItem runat="server">test3</asp:ListItem> </asp:BulletedList> <asp:BulletedList id="List2" BulletSyle="Numbered"      FirstBulletNumber="4" DisplayMode="Text"      runat="server">   <asp:ListItem runat="server">test1</asp:ListItem>   <asp:ListItem runat="server">test2</asp:ListItem>   <asp:ListItem runat="server">test3</asp:ListItem> </asp:BulletedList> 

The second BulletedList control shown in Listing 12.1 also specifies the DisplayMode property (attribute), which is a value from the Bulleted ListDisplayMode enumeration. The default if not specified is Text . The other two options for this property are HyperLink , which turns each item in the list into a hyperlink, and LinkButton , which renders each item with an attached JavaScript URL that runs client-side code to submit the form (it works just like a standard LinkButton) .

Listing 12.2 shows these two options in use. The first sets the bullet style to a square and specifies that the list items should be displayed as hyperlinks . The Value property of the ListItem control is used as the href attribute of the hyperlink. If the Value property is not declared (as in the third item), the Text property is used instead.

Listing 12.2 A BulletedList Using Hyperlinks
 <asp:BulletedList id="List3" DisplayMode="HyperLink"      BulletSyle="Square" runat="server">   <asp:ListItem Text="test1" runat="server"                 Value="http://www.mypage.aspx" />   <asp:ListItem Text="test2" runat="server"                 Value="http://otherpage.aspx" />   <asp:ListItem Text="test3" runat="server" /> </asp:BulletedList> <asp:BulletedList id="List4" DisplayMode="LinkButton"      BulletSyle="CustomImage" BulletImageUrl="bullet.gif"      runat="server">   <asp:ListItem Text="test1" runat="server" />   <asp:ListItem Text="test2" runat="server" />   <asp:ListItem Text="test3" runat="server" /> </asp:BulletedList> 

The declaration of the fourth BulletedList control in our series of examples (i.e., the second control in Listing 12.2) shows the use of the value CustomImage for the BulletStyle property, with the URL of the image provided in the BulletImageURL property. We've also specified LinkButton for the DisplayMode property, so each item will be rendered in the page as a link button (a hyperlink that uses a JavaScript URL to submit the form containing the control).

Data Binding to a BulletedList Control

The BulletedList class exposes the same properties, methods , and events as the ListControl and DataBoundControl classes from which it inherits, so we can use standard data binding techniques, just like we would with a DropDownList or ListBox control. First we declare the BulletedList with no content:

 <asp:BulletedList id="List2" BulletSyle="Numbered"      FirstBulletNumber="4" DisplayMode="Text"      runat="server" /> 

Then we assign a suitable data source to the DataSource property of the control at runtime. In Listing 12.3, we use a simple routine that creates a String array and assign the array to the BulletedList during the Page_Load event.

Listing 12.3 A Data-Bound BulletedList Control
 Sub Page_Load()   If Not Page.IsPostback Then     List2.DataSource = GetListArray()     Page.DataBind()   End If End Sub Function GetListArray() As String()   Dim aList(2) As String   Dim iLoop As Integer   For iLoop = 1 To 3     aList(iLoop - 1) = "bound item " & iLoop.ToString()   Next   Return aList End Function 

Figure 12.1 shows the four instances of the BulletedList control we've described so far, with the second one having the literal content replaced by data binding as demonstrated in Listing 12.3. You can see in the first "column" of the figure that the first BulletedList control displays a "normal" <ul> list, and the second displays a numeric <ol> ordered list starting at 4 and containing our data-bound values. The third instance, at the top of the second "column," displays hyperlinks, and the fourth uses link buttons (though these two do, of course, look just the same in the page).

Figure 12.1. The BulletedList control in action

graphics/12fig01.gif

Detecting Which Item Was Clicked in a BulletedList Control

One reason for using LinkButton controls in the list is to cause a postback so that you can handle the user 's selection (using Hyperlink controls means that the user will navigate directly to the page specified in the list). The OnClick attribute specifies the event handler that will be executed on a postback.

This event handler accepts a BulletedListEventArgs object, which has the single property Index containing the index of the item that was clicked. The code shown in Listing 12.4 just displays that index in a Label control on the page.

Listing 12.4 Specifying an OnClick Event Handler
 <asp:BulletedList id="List4" DisplayMode="LinkButton"      BulletSyle="CustomImage" BulletImageUrl="bullet.gif"  OnClick="ShowItem"  runat="server">   <asp:ListItem Text="test1" runat="server" />   <asp:ListItem Text="test2" runat="server" />   <asp:ListItem Text="test3" runat="server" /> </asp:BulletedList> <asp:Label id="lblResult" runat="server" /> <script runat="server"> Sub ShowItem(Sender As Object, E As BulletedListEventArgs)   lblResult.Text = "Selected item index is: " & E.Index End Sub </script> 

The FileUpload Control

Uploading files to the server in ASP.NET 1.x is accomplished by using the HtmlInputFile control from the HtmlControls namespace, as <input type="file" runat="server"> . In ASP.NET 2.0, there is a new FileUpload control that considerably simplifies the work required to upload files. It exposes properties that provide a reference to the uploaded (or "posted" file) and details about the file.

The FileUpload control must be placed on a server-side form, though there is no need to specify the enctype attribute for the form, as you previously had to do with the HtmlInputFile control. When ASP.NET 2.0 detects that a form contains a FileUpload control, it automatically adds the attribute enctype="multipart/form-data" to the form. Listing 12.5 shows how easy it is to declare the control, together with the AlternateText that will be displayed if the current client's browser doesn't support file uploads.

Listing 12.5 Using the FileUpload Control
 <form runat="server"> <asp:FileUpload id="MyFile" runat="server"      AlternateText="Sorry, cannot upload files" /><p/> <asp:Button id="btnUpload" Text="Go" runat="server"             OnClick="GetFile" /><p /> <asp:Label id="lblResult" runat="server" /> </form> 

We've included a Button control to start the upload and a Label control that will display the results of the process. The Button control generates an HTML submit button, and this will cause the file that the user chooses in the FileUpload control to be posted to the server. However, the OnClick attribute of the button will also cause the event handler named GetFile to run when the postback occurs. The code in this event handler is responsible for collecting the file from the request and storing it on disk (see Listing 12.6).

Listing 12.6 Processing the Uploaded File
 Sub GetFile(Sender As Object, E As EventArgs)   ' first see if a file was posted to the server   If MyFile.HasFile Then     Try       ' display just the filename       lblResult.Text = "Uploading '" & _                      MyFile.FileName & "'...<br />"       ' save to disk with specified path       ' and existing filename       MyFile.SaveAs("D:\Temp\" & MyFile.FileName)       ' display results       ' - FileName of PostedFile contains the full       ' - path entered into the       ' - FileUpload control textbox by the user       lblResult.Text &= "Received '" _           & MyFile.PostedFile.FileName _           & "Type: " _           & MyFile.PostedFile.ContentType _           & "Length: " _           & MyFile.PostedFile.ContentLength.ToString() _           & " bytes"     Catch       lblResult.Text &= "Cannot save uploaded file"     End Try   Else     lblResult.Text &= "No file received"   End If End Sub 

Figure 12.2 shows the results. You can see from the preceding code that the file was uploaded and stored in D:\Temp on the server. Note that a full path for the saved file must be used, otherwise an exception occurs.

Figure 12.2. The FileUpload control in action

graphics/12fig02.gif

The maximum size of a file that can be uploaded is governed by the maxRequestLength value in the <httpRuntime> section of machine.config . The default is 4096K. You can change it in machine.config to a larger or smaller value, or you can do the same in the web.config file for your application.

The HiddenField Control

Hidden-type <input> elements are useful for storing values in a Web page, especially where you don't want to rely on using ASP.NET sessions. In ASP.NET 1.x, the only way to generate a hidden control is by using the HtmlInputHidden control from the HtmlControls namespace, as <input type="hidden" runat="server"> . In ASP.NET 2.0, the new HiddenField control can be used instead.

One nice feature of this control is the ability to detect changes to the value after a postback. This is useful if the page uses hidden controls to submit values to the server because the OnValueChanged event of the HiddenField control is raised on the server after a postback only when the value currently in the control is different from that when the page was sent to the client.

Listings 12.7 through 12.9 demonstrate this. The server-side form contains a HiddenField control, together with two buttons. The first is a simple HTML button that only runs a client-side script function named ChangeValue . The other is an ASP.NET Button control that submits the form to the server. Finally, there is a Label control to display the results.

Listing 12.7 Declaring the HiddenField Control
 <form runat="server">   <asp:HiddenField id="MyField" Value="some value"        OnValueChanged="ShowValue" runat="server" /><p/>   <input type="button" Value="Change value"       onclick="ChangeValue()">   <asp:Button Text="Submit" runat="server" /><p />   <asp:Label id="lblResult"       Text="Field contains: 'some value'" runat="server" /> </form> 

The client-side script function is listed next (see Listing 12.8). All it does is change the value in the first control on the first <form> of the page to include the current date and time, then display a confirmation message.

Listing 12.8 Accessing the HiddenField Content in Client Script
 <script language="JavaScript"> // NB: this is client-side script function ChangeValue() {   var ctrl = document.forms[0].elements['MyField'];   ctrl.value = 'Whoops, I changed it on ' + Date() + '!';   alert('OK, I changed it'); } </script> 

The server-side code that runs when the Submit button is clicked is even simpler (see Listing 12.9). It just displays the value of the HiddenField control in the Label control on the page. Value is the only property exposed by the HiddenField control in the Technology Preview version of ASP.NET 2.0.

Listing 12.9 Accessing the HiddenField Content in Server Script
 Sub ShowValue(oSender As Object, oArgs As EventArgs)   lblResult.Text = "New value is '" & MyField.Value & "'" End Sub 

Figure 12.3 shows the result. Clicking the Change value button updates the HiddenField , and then the Submit button posts the form containing the control to the server. If the value has been changed, the ValueChanged event is raised and the new value is displayed.

Figure 12.3. The HiddenField control in action

graphics/12fig03.gif

The Table Control

ASP.NET 2.0 automatically adapts the output it generates to suit different types of clients , as we saw in Chapter 10. One specific issue is with devices that have only limited screen real estate availablecellular phones are a prime example. If you want to display a table but the page may be delivered to a small-screen device, it's likely that device will not be able to display the information in any meaningful way.

The ideal approach for a small-screen device is to break up the table into individual rows and display these separately. But for the user to be able to grasp the whole picture, he or she needs to see how many rows there are and look at each one individually or choose one from the table. Conversely, in a normal Web browser, the user generally wants to see the whole table.

Three Views of the Content

To meet these requirements, the Table control automatically provides three views of the data in a table. For normal Web browsers, it outputs a standard HTML table. By taking advantage of the new header and footer rows features, you can generate a table that contains <th> elements as well as the usual <td> elements (see Figure 12.4).

Figure 12.4. The Table control from a Windows browser

graphics/12fig04.gif

However, the same page viewed in a cellular phone contains a table with the same number of rows but only one column. This view is called summary view , and the column shown is the summary column . Notice that each row (except for the header and footer) is a link that can be followed (see Figure 12.5).

Figure 12.5. The Table control from a phone browser

graphics/12fig05.gif

Activating the link for any of the rows switches the page to details view . In this view, all the columns for the selected row are displayed (see Figure 12.6). At the bottom of the page are links that allow the user to go back to summary view or move to the next or previous row. So the user can easily browse the table, and the developer didn't have to do anything to make all this happen!

Figure 12.6. Paging a Table control

graphics/12fig06.gif

The Code to Build the Table

The page you've been looking at contains four rows of three columns, with each cell containing the row and column number so that you can see what's happening. The Table control itself is declared in the page, but with no rows defined. (Note that it has to be located on a server-side form.)

 <form runat="server"> <asp:Table id="MyTable" GridLines="Both" runat="server" /> </form> 

The page also contains a subroutine named CreateTable that dynamically builds the rows for the table and adds them to the Table control (see Listing 12.10). The technique is the same as that used with the ASP.NET 1.x Table control, but here we're taking advantage of the new TableHeaderRow and TableFooterRow controls to create the header and footer rows.

Listing 12.10 Creating a Table Control Dynamically
 Sub CreateTable()   Dim Rows As Integer = 4   Dim Cols As Integer = 3   Dim RowCount, ColCount As Integer   Dim Row As TableRow   Dim Cell As TableCell   ' header row   Row = New TableHeaderRow()   For ColCount = 0 To Cols - 1     Cell = New TableHeaderCell()     Cell.Controls.Add( _            New LiteralControl("Header" & ColCount))     Row.Cells.Add(Cell)   Next   MyTable.Rows.Add(Row)   ' data rows   For RowCount = 0 To Rows - 1     Row = New TableRow()     For ColCount = 0 To Cols - 1       Cell = New TableCell()       Cell.Controls.Add( _              New LiteralControl("Row" _               & RowCount & " Col" & ColCount))       oRow.Cells.Add(Cell)     Next     MyTable.Rows.Add(Row)   Next   ' footer row   Row = New TableFooterRow()   For ColCount = 0 To Cols - 1     Cell = New TableCell()     Cell.Controls.Add( _            New LiteralControl("Foot" & ColCount))     oRow.Cells.Add(Cell)   Next   MyTable.Rows.Add(Row) End Sub 

Then, in the Page_Load event, we can call this routine when the page loads each time:

 Sub Page_Load()   CreateTable() End Sub 

This is all that's required. Of course, we could simply declare each row of the table using the usual <tr> , <th> , and <td> elements, without building it at runtime using code. However, in that case, the header and footer rows will be treated as "ordinary rows" and will be selectable in summary view.

Programmatically Selecting the View Mode and Row

When the Table control is serving content to a small-screen device, the view mode can be selected by using the ViewMode property (the options from the TableViewMode enumeration are Details and Summary ) or by adding the ViewMode attribute to the declaration of the Table control (see Listing 12.11). And when the table is in details mode, the current row (the row actually being displayed) can be specified by using the CurrentRow property. Of course, you probably want to do this only when the page is first loaded, and not on a postback, or the user will not be able to browse from row to row and switch from one mode to the other.

Listing 12.11 Setting the ViewMode of a Table Control
 Sub Page_Load()   CreateTable()   If Not Page.IsPostback Then     MyTable.ViewMode = TableViewMode.Details     MyTable.CurrentRow = 1   End If End Sub 

By default, the column displayed in summary view mode is the one at index (the first column). However, you can change this by specifying the index of any other column in the table for the SummaryViewColumnIndex property or by adding the attribute SummaryViewColumnIndex=" index " to the declaration of the Table control. And if the table has more than one header row, you can specify which one is used in details view mode with the DetailsHeaderRowIndex property.

You can also change the text displayed for the links below the row details in details view mode by setting the DetailNextRowText , DetailPrevRowText , and DetailSummaryRowText properties or attributes to the String values you require. And there are "style" properties for each section of the table in both view modes as well.

Finally, it's also possible to specify extra information for the table as a whole in the Summary property and for each details view in the DetailSummaryText property for each cell. (Some specialist user agents and aural page readers will use these values when they cannot display the table.)

The DynamicImage Control

We've just seen how the Table control in ASP.NET 2.0 automatically adapts its output to better suit the limited screen space available on some devices, in particular cellular phones. However, another issue arises with these kinds of devices in that many don't recognize the common image types used in HTML, such as the .gif , .png , and .jpg formats. To get around this problem, you can use a new control named DynamicImage .

The DynamicImage control uses the Image Generation Service, accessed via a special .axd HTTP handler, to dynamically generate a suitable stream of bytes for the image, rather than the more usual technique of specifying a file on the server as the src attribute of an <img> element. By providing the correct MIME type when it responds to the request for the image stream, the DynamicImage control ensures that the client can display the image just as it would an image file from disk.

The DynamicImage control can also accept as its image source an array of bytes that represents the image or a reference to an ImageGenerator service that "contains" an image that has been created using drawing commands. You can create classes that inherit from ImageGenerator and that create an image, then use these as the input to the DynamicImage control.

To demonstrate the basic uses of the DynamicImage control, the following code declares two instances of the control. The first (see Listing 12.12) simply uses a disk file named car.gif , specifying that it is an image file on disk in the DynamicImageType property (attribute). The second of the control instances specifies ImageBytes for the DynamicImageType property, so the control will expect to receive a reference to a Byte array containing the data for the image.

Listing 12.12 Declaring the DynamicImage Control
 <form runat="server"> <asp:DynamicImage DynamicImageType="ImageFile"                   ImageFile="car.gif" runat="server" /> <asp:DynamicImage DynamicImageType="ImageBytes"                   id="MyImage" runat="server" /> </form> 

This image data is generated in code and then assigned to the ImageBytes property at runtime. Listing 12.13 shows the code we used.

Listing 12.13 Streaming Content into the DynamicImage Control
 Sub Page_Load()   Dim Stream = New FileStream("c:\temp\car.gif", _                FileMode.Open, _                FileAccess.Read)   Dim MyArray(oStream.Length - 1) As Byte   Stream.Read(MyArray, 0, Stream.Length)   Stream.Close   MyImage.ImageBytes = MyArray End Sub 

You can see that we are simply opening the image file on disk and reading it into the array as a stream. Of course, you would probably store the image data in a database instead and stream it from there into an array. The final line of code in the Page_Load event handler shown in Listing 12.13 then assigns the array to the ImageBytes property of the DynamicImage control. Figure 12.7 shows the output generated by these two DynamicImage controls.

Figure 12.7. The DynamicImage control from a Windows browser

graphics/12fig07.gif

The DynamicImage control can also be used to convert images between different types. For example, consider the following:

 <asp:DynamicImage runat="server"     imageType="Jpeg"     imageFile="logo.gif" /> 

This converts logo.gif into a JPEG file.

Automatic Translation of Images for Other Devices

When a DynamicImage control is used in a page that is being served to a non-HTML device, such as a cellular phone, the Image Generation Service that is generating the image automatically converts the image into the correct representation for the device where possible. Opening a page that contains just the first instance of the DynamicImage control shown in Listing 12.12 results in the following output being sent to the client in response to the GET request for the image:

 HTTP GET Request: HTTP://LOCALHOST/aspnet20/ch03/CachedImageService.axd?data=07c e61a2-b688-436a-9cb1-c94f91d582e4 ----------------- DATA SIZE ------------------------ Uncompiled data from HTTP is 1373 bytes. ...found Content-Type: image/vnd.wap.wbmp. Compiled WAP binary is 1458 bytes. ---------------------------------------------------- Measured image is 150 x 72 

You can see that now it appears as a .wbmp file, with the content type image/vnd.wap.wbmp , and it looks like Figure 12.8.

Figure 12.8. The DynamicImage control from a phone browser

graphics/12fig08.gif

The Image Generation Service

ASP.NET 2.0 introduces several new extensions for file types, such as themes, skins, and masters, and although these are part of the page architecture, they aren't ASP.NET pages themselves . The Image Generation Service, however, introduces a new type ( .ASIX ) to ease the dynamic creation of images. It was possible to create images dynamically in ASP.NET 1.x, but there was no standard way to do ityou invariably used an ASP.NET page or a Web Service, created the image, and then saved it to the output stream.

With ASP.NET 2.0 there is a base control, ImageGenerator , that provides much of this default behavior. All you need to do is inherit from this control and then perform the actual drawing. For example, Listing 12.14 shows how an .ASIX file could be used.

Listing 12.14 Using the ImageGenerator Control
 <%@ Image Class="Test" Language="VB" %> Imports System Public Class Test   Inherits System.Web.UI.Image.ImageGenerator     Protected Overrides Sub RenderImage(g As Graphics)       g.FillRectangle(Brushes.Black, g.ClipBounds)       Dim f As New Font("Ariel", 22)       g.DrawString("Welcome", f, _         Brushes.White, 0, 0)       g.DrawString("to our site", f, _         Brushes.White, 10, 30)     End Sub End Class 

This simply draws a rectangle and then two lines of text, resulting in the image shown in Figure 12.9.

Figure 12.9. The ImageGenerator control in action

graphics/12fig09.gif

The beauty of this method of image creation is its simplicityall you have to do is concentrate on creating the image itself, letting the Framework handle how it is to be rendered to the browser.

Image Generation Service Configuration

The Image Generation Service can be configured by modifying the imageGeneration section in web.config or machine.config . The syntax is shown below:

 <system.web>     <imageGeneration         storageType="[CacheDisk]"         storageExpiration="[  number  ]"         storagePath="[  string  ]" /> </system.web> 

The attributes are detailed in Table 12.1.

Table 12.1. Image Generation Configuration Attributes

Attribute

Description

storageType

Determines where the images will be stored. The default is Cache .

storageExpiration

Sets the number of seconds until the image expires . The default is 300 .

storagePath

Indicates the location for images if Disk storage is used. An empty string (the default) will cause an exception if storageType is Disk .

The MultiView and View Controls

If you installed and played with the Internet Explorer Web Controls pack in ASP.NET 1.x, you were probably impressed with the way you can easily create quite complex effects that are common in executable applications in a Web page. One of the many useful controls in the Internet Explorer Web Controls pack is the MultiView control. This control allows you to declare several "screens" or "views," which are each separate sections of the UI for a page, and then display any one of them in the page on demand.

However, while the Internet Explorer Web Controls version can take advantage of some clever client-side code to provide these features in Internet Explorer without requiring a postback, the MultiView control in ASP.NET 2.0 works only with a postback to the server every time you want to change the screen or view displayed.

To declare a MultiView control and its content, you use the ASP.NET MultiView as the container and then place within it one or more View controls. Listing 12.15 shows a simple MultiView declaration containing two View controls. Each View contains just a Label control and a Button control.

Listing 12.15 Declaring the MultiView Control
 <asp:MultiView id="MyMulti"     ActiveViewIndex="0" runat="server">   <asp:View id="View1">     <asp:Label id="lblView1"         Text="This is View 1" runat="server" /><p />     <asp:Button id="btnView1" Text="Next"         OnClick="ShowNext" runat="server" />     </asp:View>   <asp:View id="View2">     <asp:Label id="lblView2" Text="This is View 2"       runat="server" /><p />     <asp:Button id="btnView2" Text="Previous"       OnClick="ShowPrev" runat="server" />   </asp:View> </asp:MultiView><p /> 

The MultiView control chooses which View to display based on the value of the ActiveViewIndex property (indexed from ). By default this property is set to -1 (no View is shown), so when the page loads for the first time we specify that the first of the View controls should be displayed by setting the ActiveViewIndex attribute to . We could alternatively set it in code in a Page_Load event handler.

In the View controls, the two buttons named ShowNext (in the first view) and ShowPrev (in the second view) execute event handlers when clicked. We've also included a Button and a Label control on this page, but outside the MultiView control.

 <asp:Button id="btnSetView2" Text="Go to View 2"             OnClick="ShowView2" runat="server" /><p /> <asp:Label id="lblStatus" runat="server" /> 

This Button control executes an event handler named ShowView2 , which switches the MultiView control to display the second view (indexed 1), and the Label control is used to display the current value of the ActiveViewIndex property. The code to implement these three event handlers appears in Listing 12.16.

Listing 12.16 Moving between the Views
 Sub ShowNext(oSender As Object, oArgs As EventArgs)   MyMulti.ActiveViewIndex += 1   lblStatus.Text = "ActiveViewIndex = " _            & MyMulti.ActiveViewIndex End Sub Sub ShowPrev(oSender As Object, oArgs As EventArgs)   MyMulti.ActiveViewIndex -= 1   lblStatus.Text = "ActiveViewIndex = " _            & MyMulti.ActiveViewIndex End Sub Sub ShowView2(oSender As Object, oArgs As EventArgs)   MyMulti.ActiveViewIndex = 1   lblStatus.Text = "ActiveViewIndex = " _            & MyMulti.ActiveViewIndex End Sub 

You can see that all these event handlers do is set the ActiveViewIndex property to the appropriate value and then display this value in the Label control. Figure 12.10 shows the results.

Figure 12.10. The MultiView control in action

graphics/12fig10.gif

Navigating Using Query String Values

As well as setting the ActiveViewIndex property directly, you can have this automatically set from a query string value (see Listing 12.17).

Listing 12.17 Setting the ActiveViewIndex from a QueryString
 <asp:MultiView id="MyMulti" runat="server"     QueryStringParam="view">   <asp:View id="View1">     ...   </asp:View>   <asp:View id="View2">     ...   </asp:View> </asp:MultiView> 

Now the current view will be changed depending on the value of the View control's query string parameter. For example:

http://www.somesite.com/default.aspx?view=View1

Navigating Views Using Commands

Navigation can also be automatic from controls that support the CommandName and CommandArgument properties, such as the Button and LinkButton controls. When these properties are set on controls within the MultiView , switching views will automatically take place depending on the property values.

For example, consider the code in Listing 12.18.

Listing 12.18 Using Commands to Navigate through a MultiView Control
 <asp:MultiView id="MyMulti" runat="server"   <asp:View id="View1">     <asp:Button Text="Next" runat="server"  CommandName="NextView" />  <asp:Button Text="Go to 2" runat="server"  CommandName="SwitchViewByID"   CommandArgument="View2" />  </asp:View>   <asp:View id="View2">     <asp:Button Text="Prev" runat="server"  CommandName="PrevView" />  <asp:Button Text="Go to 1" runat="server"  CommandName="SwitchViewByIndex"   CommandArgument="0" />  </asp:View> </asp:MultiView> 

When CommandName is NextView or PrevView , the active View is automatically switched when the button is clicked. If CommandName is SwitchViewByID , the CommandArgument should contain the ID of the View to switch to, which happens automatically when the button is clicked. With CommandName set to SwitchViewByIndex , the CommandArgument should be the index number ( zero-based ) of the View to switch to.

The CommandName values can be changed by changing the values defined by four static fields of the MultiView (see Table 12.2).

Table 12.2. MultiView CommandName Properties

Field

Description

NextViewCommandName

A string containing the name of the command that moves to the next View . The default value is NextView .

PrevViewCommandName

A string containing the name of the command that moves to the previous View . The default value is PrevView .

SwitchViewByIDCommandName

A string containing the name of the command that moves to the View whose ID is given in the CommandArgument property. The default value is SwitchViewByID .

SwitchViewByIndexCommandName

A string containing the name of the command that moves to the View whose index is given in the CommandArgument property. The default value is SwitchViewByIndex .

Obviously you can include a lot more views or screens in a MultiView than we've shown in the preceding samples, and the handy thing is that all the controls declared in all the views are available to your server-side code, even when not included in the output sent to the client. They all maintain their values using the viewstate of the page, so it's easy to build tabbed dialogs or wizard-style pages using this control. (However, if you really want to build wizards for your Web applications, the Wizard control makes it even easier.)

Other features implemented in the MultiView for the Technology Preview release (there are more coming up for the final release) extend the ways you can use the MultiView . The View controls declared within the MultiView are exposed through the Views property, which is a reference to a ViewCollection . Each member of the collection is a View , and the collection has the Add( view As Control) and AddAt( index As Integer, view As Control) methods so that you can change the views available at runtime. And there is also an ActiveViewChanged event for the MultiView control that can be handled by specifying an event handler for the OnActiveViewChanged property or attribute.

The ImageMap Control

The ImageMap control provides a server implementation of the HTML MAP element, allowing sections of images to be used as clickable hot spots. There are three hot spot types:

  • RectangleHotSpot , to define the bounds of a rectangular portion of the image

  • CircleHotSpot , to define the bounds of a circular portion of the image

  • PolygonHotSpot , to define the bounds of an irregular portion of the image

The syntax for the ImageMap control is shown below:

 <asp:ImageMap id="  String  " runat="server"   HotSpotMode="[NavigatePostback]"   ImageUrl="  String  "   /> 

The properties are described in Table 12.3.

Table 12.3. ImageMap Properties

Property/Attribute

Description

HotSpotMode

Sets or returns the mode in which hot spots work. This can be one of the HotSpotMode enumerations:

  • Navigation : Indicates that navigation takes place when the hot spot is clicked. In this mode the Value property of the hot spot should contain the Url of the target navigation.

  • Postback : Indicates that postback should take place when the hot spot is clicked. In this mode the contents of the hot spot's Value property are passed into the server-side event handler.

HotSpots

Returns a HotSpotCollection containing all defined hot spot regions .

ImageUrl

Sets or returns the Url to the image.

SiteCounterProvider

Indicates the site counter provider to use.

In addition to these properties, the ImageMap control implements the Site Counters Service and therefore supports the following properties:

  • CountClicks

  • CountGroup

  • CounterName

  • RowsPerDay

  • TrackApplicationName

  • TrackNavigateUrl

  • TrackPageUrl

Specifying Hot Spots

On its own the ImageMap control isn't much use because you need to specify the areas within the image that will act as hot spots, as well as what happens when those regions are clicked. For example, consider the page shown in Figure 12.11, which has two rectangular hot spot regions and one circular region. The code to implement this appears in Listing 12.19.

Listing 12.19 Declaring the ImageMap Control
 <asp:ImageMap id="YesNoMaybe"  runat="server"   ImageUrl="YesNoMaybe.jpg" onClick="ImageClicked">    <asp:RectangleHotSpot            Top="3" Left="3"            Right="68" Bottom ="68"            HotSpotMode="Postback"            Value="Yes"            AlternateText="Yes, I love ASP.NET" />    <asp:RectangleHotSpot            Top="3" Left="86"            Right="149" Bottom ="68"            HotSpotMode="Postback"            Value="No"            AlternateText="No, I don't love ASP.NET" />    <asp:CircleHotSpot            x="78" y="104"            Radius="22"            HotSpotMode="Navigate"            Value="http://www.asp.net/"            AlternateText="I don't know" /> </asp:ImageMap> 
Figure 12.11. Sample ImageMap Control

graphics/12fig11.gif

The RectangleHotSpot has four properties to define its region Top , Left , Right , and Bottom which contain pixel values. The CircleHotSpot has three properties x and y to define the center point and Radius to define the circle radius. Both types of controls have an AlternateText property, for the tooltip text, as well as HotSpotMode and Value properties to define what action is to be taken when the image region is clicked. If the HotSpotMode is Navigate , the Value is used as the URL to navigate to; if it is Postback , the Value is passed into the event procedure defined by the onClick property of the ImageMap . The event procedure could look something like Listing 12.20.

Listing 12.20 Implementing the onClick Event Handler
 Sub ImageClicked(Sender As Object, E As ImageMapEventArgs)   Select Case E.Value   Case "Yes"     ' take some action   Case "No"     ' take some action   End Select End Sub 
Irregular Hot Spots

Irregular hot spots are enabled by a PolygonHotSpot control that defines a series of x- and y-coordinates that define the bounds of the image region. For example, consider a map of the United Kingdom, perhaps used to pick sales regions, as shown in Figure 12.12. To set hot spots for the regions, we would use code like Listing 12.21.

Listing 12.21 Defining Irregular Hot Spots
 <asp:ImageMap id="UKMap" runat="server"     HotSpotMode="Postback"     ImageUrl="UKMap.jpg" onClick="MapClicked">   <asp:PolygonHotSpot       Coordinates="205,17,328,38,346,99,200,160,270,132"       Value="North Scotland"/>   <asp:PolygonHotSpot       Coordinates="209,166,225,224,339,200,335,112"       Value="South Scotland"/>   <asp:CircleHotSpot  x="411" y="452" radius="11"       Value="London"/>   ... </asp:ImageMap> 
Figure 12.12. ImageMap of the United Kingdom

graphics/12fig12.gif

There is no real limit to the number of coordinates you put inmore of them leads to a finer-grained and smoother polygon but is more time consuming to type. In reality you don't have to be 100% accurate to the area you are defining because users tend to click near the middle of a region anyway.



A First Look at ASP. NET v. 2.0 2003
A First Look at ASP. NET v. 2.0 2003
ISBN: N/A
EAN: N/A
Year: 2004
Pages: 90

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net