Custom Controls


In the past it has been tricky to implement custom-built controls, especially on large-scale systems where complex registration procedures might be required in order to use them. Even on simple systems, the coding required to create a custom control could become a very involved process. The scripting capabilities of older Web languages also suffered by not giving the perfect access to your cunningly crafted object models, and resulted in poor performance all around.

The .NET Framework provides an ideal setting for the creation of custom controls, using simple programming techniques. Every aspect of ASP.NET server controls is exposed for you to customize, including such capabilities as templating and client-side scripting. However, there is no need to write code for all of these eventualities; simpler controls can be a lot easier to create.

In addition, the dynamic discovery of assemblies that is inherent in a .NET system makes installation of Web applications on a new Web server as simple as copying the directory structure containing your code. To make use of the controls you have created you simply copy the assemblies containing those controls along with the rest of the code. You can even place frequently used controls in an assembly located in the global assembly cache (GAC) on the Web server, so that all Web applications on the server have access to them.

This chapter discusses two different kinds of controls:

  • User controls (and how to convert existing ASP.NET pages into controls)

  • Custom controls (and how to group the functionality of several controls, extend existing controls, and create new controls from scratch)

User controls are illustrated with a simple control that displays a card suit (club, diamond, heart, or spade), so that you can embed it in other ASP.NET pages with ease. In the case of custom controls, you won't go into too much depth, although you will see the basic principles and be pointed to where you can find out more.

User Controls

User controls are controls that you create using ASP.NET code, just as you would in standard ASP.NET Web pages. The difference is that after you have created a user control you can reuse it in multiple ASP.NET pages with a minimum of difficulty.

For example, say that you have created a page that displays some information from a database, perhaps information about an order. Instead of creating a fixed page that does this, it is possible to place the relevant code into a user control, and then insert that control into as many different Web pages as you want.

In addition, it is possible to define properties and methods for user controls. For example, you can specify a property for the background color for displaying your database table in a Web page, or a method to re-run a database query to check for changes.

To start with, you create a simple user control. As is the case with the other chapters, you can download the code for the sample projects in this chapter from the Wrox Web site at www.wrox.com.

A simple user control

In Visual Studio .NET, create a new Web site called PCSUserCWebApp1 in the directory C:\ProCSharp\ Chapter27. After the standard files have been generated, select the Website Add New Item... menu option and add a Web User Control called PCSUserC1.ascx as shown in Figure 27-1.

image from book
Figure 27-1

The files added to your project, with the extensions .ascx and .ascx.cs, work in a very similar way to the .aspx files you've seen already. The .ascx file contains your ASP.NET code and looks very similar to a normal .aspx file. The .ascx.cs file is your code-behind file, which defines custom code for the user control, much in the same way that forms are extended by .aspx.cs files.

The .ascx files can be viewed in Design or HTML view just like .aspx files. Looking at the file in HTML view reveals an important difference: there is no HTML code present, and in particular no <form> element. This is because user controls are inserted inside ASP.NET forms in other files and so don't need a <form> tag of their own. The generated code is as follows:

 <%@ Control Language="C#" AutoEventWireup="true" CodeFile="PCSUserC1.ascx.cs" Inherits="PCSUserC1" %> 

This is very similar to the <%@ Page %> directive generated in .aspx files, except that Control is specified rather than Page. It specifies the additional code-behind file and the class name that will be generated. The generated code in the .ascx.cs file is, like in auto-generated .aspx.cs files, empty.

Your simple control will be one that displays a graphic corresponding to one of the four standard suits in cards (club, diamond, heart, or spade). The graphics required for this are shipped as part of Visual Studio .NET; you can find them in the directory C:\Program Files\Microsoft Visual Studio8\Common7\Graphics\bitmaps\assorted, with the file names CLUB.BMP, DIAMOND.BMP, HEART.BMP, and SPADE.BMP. Copy these files into a new Images subdirectory of your project's directory so that you can use them in a moment.

Note

Note that unlike earlier versions of Visual Studio, changes you make to the Web site structure outside of Visual Studio are automatically reflected in the IDE. You have to hit the refresh button in the Solution Explorer window, but you should see the new Images directory and bitmap files appear automatically.

Now add some code to your new control. In the HTML view of PCSUserC1.ascx add the following:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="PCSUserC1.ascx.cs"     Inherits="PCSUserC1" %> <table cellspacing="4"> <tr valign="middle"> <td> <asp:Image Runat="server"  ImageURL="~/Images/club.bmp"/> </td> <td> <asp:Label Runat="server" >Club</asp:Label> </td> </tr> </table> 

This defines a default state for your control, which is a picture of a club along with a label. The ~ in the path to the image means "start at the root directory of the Web site." Before you add functionality, you'll test this default by adding this control to your project Web page webForm1.aspx.

To use a custom control in an .aspx file, you first need to specify how you will refer to it, that is, the name of the tag that will represent the control in your HTML. To do this you use the <%@ Register %> directive at the top of the code in Default.aspx as follows:

 <%@ Register TagPrefix="pcs" TagName="UserC1" src="/books/4/82/1/html/2/PCSUserC1.ascx" %> 

The TagPrefix and TagName attributes specify the tag name to use (in the form <TagPrefix:TagName>), and you use the Src attribute to point to the file containing your user control. Now you can use the control by adding the following element:

<form  method="post" runat="server">   <div> <pcs:UserC1 Runat="server" />   </div> </form>

This is all you need to do to test your user control. Figure 27-2 shows the results of running this code.

image from book
Figure 27-2

As it stands, this control groups two existing controls, an image and a label, in a table layout. As such, it falls into the category of a composite control.

To gain control over the displayed suit, you can use an attribute on the <PCS:UserC1> element. Attributes on user control elements are automatically mapped to properties on user controls, so all you have to do to make this work is add a property to the code behind your control, PCSUserC1.ascx.cs. Call this property Suit, and let it take any suit value. To make it easier for you to represent the state of the control, you define an enumeration to hold the four suit names. The best way to do this is to add an App_Code directory to your Web site (App_Code is another "special" directory, like App_Data, whose functionality is defined for you — in this case it holds additional code files for your Web application), then add a .cs file called suit.cs in this directory with code as follows:

using System; public enum suit { club, diamond, heart, spade } 

The PCSUserC1 class needs a member variable to hold the suit type, currentSuit:

public partial class PCSUserC1 : System.Web.UI.UserControl { protected suit currentSuit; 

And a property to access this member variable, Suit:

 public suit Suit { get { return currentSuit; } set { currentSuit = value; suitPic.ImageUrl = "~/Images/" + currentSuit.ToString() + ".bmp"; suitLabel.Text = currentSuit.ToString(); } } 

The set accessor here sets the URL of the image to one of the files you copied earlier, and the text displayed to the suit name.

Next, you must add code to Default.aspx so you can access this new property. You could simply specify the suit using the property you have just added:

<PCS:UserC1 Runat="server"  Suit="diamond"/>

The ASP.NET processor is intelligent enough to get the correct enumeration item from the string provided. To make things a bit more interesting and interactive, though, you'll use a radio button list to select a suit:

<form  runat="server">   <div>     <pcs:UserC1  runat="server" /> <asp:RadioButtonList Runat="server"  AutoPostBack="True"> <asp:ListItem Value="club" Selected="True">Club</asp:ListItem> <asp:ListItem Value="diamond">Diamond</asp:ListItem> <asp:ListItem Value="heart">Heart</asp:ListItem> <asp:ListItem Value="spade">Spade</asp:ListItem> </asp:RadioButtonList>   </div> </form>

You also need to add an event handler for the SelectedIndexChanged event of the list, which you can do simply by double-clicking the radio button list control in Design view.

Note

Note that you have set the AutoPostBack property of this list to True, because the suitList_ SelectedIndexChanged() event handler won't be executed on the server unless a postback is in operation, and this control doesn't trigger a postback by default.

The suitList_SelectedIndexChanged() method requires the following code in Default.aspx.cs:

public partial class Default {    protected void suitList_SelectedIndexChanged(object sender, EventArgs e)    { myUserControl.Suit = (suit)Enum.Parse(typeof(suit), suitList.SelectedItem.Value);    } }

You know that the Value attributes on the <ListItem> elements represent valid values for the suit enumeration you defined earlier, so you simply parse these as enumeration types and use them as values of the Suit property of your user control. You cast the returned object type to suit using simple casing syntax, as this can't be achieved implicitly.

Now you can change the suit when you run your Web application (see Figure 27-3).

image from book
Figure 27-3

Next, you'll give your control some methods. Again, this is very simple; you just add methods to the PCSUserC1 class:

 public void Club() { Suit = suit.club; } public void Diamond() { Suit = suit.diamond; } public void Heart() { Suit = suit.heart; } public void Spade() { Suit = suit.spade; } 

These four methods — Club(), Diamond(), Heart(), and Spade() — change the suit displayed on the screen to the respective suit clicked.

You'll call these functions from four ImageButton controls in your .aspx page:

</asp:RadioButtonList> <asp:ImageButton Runat="server"  ImageUrl="~/Images/CLUB.BMP" OnClick="clubButton_Click" /> <asp:ImageButton Runat="server"  ImageUrl="~/Images/DIAMOND.BMP" OnClick="diamondButton_Click" /> <asp:ImageButton Runat="server"  ImageUrl="~/Images/HEART.BMP" OnClick="heartButton_Click" /> <asp:ImageButton Runat="server"  ImageUrl="~/Images/SPADE.BMP" OnClick="spadeButton_Click" />   </div> </form>

You'll use the following event handlers:

 protected void clubButton_Click(object sender, ImageClickEventArgs e) { myUserControl.Club(); suitList.SelectedIndex = 0; } protected void diamondButton_Click(object sender, ImageClickEventArgs e) { myUserControl.Diamond(); suitList.SelectedIndex = 1; } protected void heartButton_Click(object sender, ImageClickEventArgs e) { myUserControl.Heart(); suitList.SelectedIndex = 2; } protected void spadeButton_Click(object sender, ImageClickEventArgs e) { myUserControl.Spade(); suitList.SelectedIndex = 3; } 



Professional C# 2005
Pro Visual C++ 2005 for C# Developers
ISBN: 1590596080
EAN: 2147483647
Year: 2005
Pages: 351
Authors: Dean C. Wills

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