Have a question? ask www.kenlet.com
Home  |  FAQ  |  About  |  Contact  |  View Source   
 
SEARCH:
 
BROWSE:
    My Hood
Edit My Info
View Events
Read Tutorials
Training Modules
View Presentations
Download Tools
Scan News
Get Jobs
Message Forums
School Forums
Member Directory
   
CONTRIBUTE:
    Sign me up!
Post an Event
Submit Tutorials
Upload Tools
Link News
Post Jobs
   
   
Home >  Tutorials >  C# >  Creating Custom Web Controls in C#
Add to MyHood
   Creating Custom Web Controls in C#   [ printer friendly ]
Stats
  Rating: 4.08 out of 5 by 13 users
  Submitted: 10/03/01
Peter Weng ()

 
By now you may or may not have heard of ASP.NET's Web Controls. In this tutorial I plan to discuss the advantages of using Web Controls, as well as how to create and deploy them in C#.

What are Web Controls?

Web Controls are widgets that can be reused across multiple webpages. Controls may render HTML to the client, or other formats such as WML or XML. If you're familiar with ASP.NET, you'll know that ASP.NET provides some controls for you right out of the box. These include DataGrids, Calendars, AdRotators, etc.

Why use User Controls?

The biggest advantage of Web Controls is code reuse. Because they can be reused across multiple pages in different ways, Web Controls can save you the hassle of writing similar HTML on multiple pages by generating the appropriate HTML for you.

But why use C#? Can't we just use .ascx files?
.ascx files are another way of creating reusable controls. However, it doesn't always provide a clean way of separating your code from content. What this means is that content developers can write content, graphic artists and UI experts can layout your site, and you can develop the logic behind everything without overlapping each other. In addition, when deploying your web site or giving your web site to someone else, by using controls written in C# and pre-compiled, you won't have to give them any of your source code to launch your site, all you need to give them are the dll's which contain your compiled source code for your control.

What are we going to build today?
Today we'll be taking apart one of the components of DevHood. If you look at the top of most of our pages, you'll notice a Yahoo! style navigation bar that looks something like this:


Home > Tutorials > General ASP.NET > Creating Custom Web Controls


This navigation bar is actually generated dynamically for each page by a Custom Web Control. Let's start by looking at the first part of the code.


namespace MyNavBar {
using System;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Collections;
using System.Drawing;


We begin by giving our Web Control a namespace, so that we can reference it in other pages. We'll also import all the namespaces we'll need for our Web Control. On .aspx pages, the following namespaces are imported by default, but for Web Controls in .cs files, you'll need to import them yourself if you'll need them:
  • System
  • System.Web
  • System.Web.UI
  • System.Web.UI.HtmlControls
  • System.Web.UI.WebControls
  • System.Collections
  • System.IO


public class NavBar : WebControl {
private string strSeperator = ">";
private int iRPad = 3;
private int iLPad = 1;

public string Seperator {
get {return strSeperator;}
set {strSeperator = value;}
}

public int LPad {
get {return iLPad;}
set {iLPad = value;}
}

public int RPad {
get {return iRPad;}
set {iRPad = value;}
}


This section of code defines the class for the Web Control, which is NavBar, and specifies it is a public class which can be instantiated by any page. We also speciify that NavBar should derive from the WwebControl class. Remember that since we imported then System.Web.UI.WebControls class we didn't need to use the full-qualified namespace reference to the WebControls class. i.e, we could just use WebControl instead of public class NavBar : System.Web.UI.WebControls.WebControl.

Next we define class variables that we'll use in building our Navigation Bar. We'll want the developer to be able to specify properties of the control such as what will be used to separate the elements, and the spacing between the seperator. You'll see what've defined class variables to hold these properties, mainly strSeperator, iLPad, iRPad. However, in order to set these properties in a page, we define the getter/setter methods for them as above.

Now we can finally get to the heart of the code. The WebControl class contains an overrideable method CreateChildControls() which is called whenever the WebControl is initialized. This is where all of our Control creation will be done.


protected override void CreateChildControls() {

//build up the Right Padding string.
string strRPad = String.Empty;
for (int i = 0; i < iRPad; i++) {
strRPad += " ";
}

//build up the Left Padding string.
string strLPad = String.Empty;
for (int i = 0; i < iLPad; i++) {
strLPad += " ";
}

Label lblSeparator;
lblSeparator = new Label();
lblSeparator.Text = strLPad + strSeparator + strRPad;



Again we'll want to start out by performing some initialization steps. First we'll build up a string containing the amount of white spaces as specified by the RPad and LPad properties. Remember, we defined the getter/setter properties for these class variables, so they can be changed by the user. The default values for them are 3 and 1, since we initialized them to these values when we defined the variables above. We also create a Label control lblSeparator which, as the name suggests, will be the separator between elements of the navigation bar. This label consists of the left padding, concatenated with the user specified Separator string (this is the string ">" by default), along with the right padding.


//iterate through the arraylist of hyperlinks and place the seperators and padding
//string in between the hyperlinks.
HyperLink hl;

hl = new HyperLink();
hl.Text = "Home";
hl.NavigateUrl = "/";
Controls.Add(hl);


Here we begin by declaring then initializing a HyperLink object. The first element of the navigation bar will always be pointing to "Home", and it's NavigateUrl will always be "/" (the root directory of your web site). Notice the line Controls.Add(hl). This adds the created "Home" HyperLink to the NavBar WebControl's ControlCollection Object. The ControlCollection Object provides a container for the NavBar to keep a list of its child controls.


//start the iteratation at i=1 because we want to disregard the first element
//of the array after the Split because it will be an empty string. We also
//want to disregard the last element of the array because that will just be
//the file name, which will be replaced with the title of the page.
string[] aPath = Page.Request.Path.Split(new Char[] {'/'});
int cntPath = aPath.Length;
string strLinkText = "";
string strCompleteUrl = "";
for (int i=1;i < cntPath; i++) {
Controls.Add(lblSeperator);

hl = new HyperLink();
strLinkText = aPath[i].ToString();
hl.Text = Char.ToUpper(strLinkText[0]) + strLinkText.Substring(1).ToLower();

strCompleteUrl += "/"+aPath[i].ToString();
hl.NavigateUrl = strCompleteUrl;

Controls.Add(hl);
}
}
}
}


Notice here how we set the aPath string array. We do this by first getting the Path from the Page's HttpRequest Object. Then we'll call C#'s Split method on the Path string. We'll want to split by the '/' character, since our website url is usually in the form https://devhood.com/subfolder1/subfolder2/page.aspx.

Now that we have split the current page's path into a string array, we can loop through this array to build up our Navigation Bar.

At each iteration of the loop, we add the Separator Label to the ControlCollection Object. Next we create a HyperLink Object consisting of the Path name as the Text, and the complete url for that Path as the NavigateUrl. Because this HyperLink Object only links to a Path, or folder in your web site, you'll need to make sure the correct default page loads up automatically when pointing to a folder of your website. For example, Microsoft IIS looks for files such as default.aspx and default.htm as the page to load when a link points to a path or folder of a website rather than a file or page. The file names and search order can be custom configured in IIS.

When we are finished creating the HyperLink object we'll add it to the ControlCollection Object as well.

Because the Add method on the Controls object appends to the end of the ControlCollection Object, we can be assured that our Navigation Bar will appear in the correct order.

That's it!! We're done. Now all that's left is to compile the code, place the dll file into our web application's bin directory and then we'll be able to use this Web Control on any of our pages by referencing it's namespace and class.

To use this control in an ASP.NET Page, we'll need to add the following directive at the top of each page:


<%@ Register TagPrefix="MyBar" Namespace="MyNavBar" %>




Then we can render this control on the page with the following line:


<MyBar:NavBar RPad=5 LPad=2 Separator=">" runat=server />



I hope this tutorial has helped you learn how to create custom controls in C#. Now you should be able to go out and create your own Navigation Bar, or other custom control in C#. Remember this Navigation Bar can easily be modified to show page titles instead of file names, or extended by adding properties to customize color, font, font-family, etc. This is left as an exercise for the reader, so go out and create a better more flexible Navigation Bar for your site from the techniques you've learned here. If you have any questions or comments, please post them below.


Return to Browsing Tutorials

Email this Tutorial to a Friend

Rate this Content:  
low quality  1 2 3 4 5  high quality

Reader's Comments Post a Comment
 
A good tutorial.
-- Brian Simoneau, March 01, 2002
 
A nice tutorial, but the code was a bit of a pain to read because the whole indenting got screwy. I never knew the top bar was dynamically done... on my old web pages I would manually type of the Home > Tutorials > Add Comment etc.. but now I shall go and reformat it to be dynamically done.
-- Victor Vuong, March 01, 2002
 
A very good tutorial!
-- Kuniaki Tran, March 03, 2002
 
It's really helpful for my first project
-- Hung Duc, October 11, 2002
 
Decent tutorial with the exception of a few mispellings. I would think that the author would actually compile the code before posting it.
-- Low Vato, June 27, 2003
 
Good article... BUT!! you out there who are not so familiere with OOP be aware that inside the for loop 'for (int i=1;i < cntPath; i++)'. You MUST instanciate a new Lable object each time or you will end up with only a seperator before the last link in the control.. This because if you use the same object as instanciated outside the for loop you will only move this object around from place to place.

so the for loop should start with something like this:

for (int i=1;i < cntPath; i++)
{
Label lblSeparator2 = new Label();
lblSeparator2.Text = strLPad + strSeparator + strRPad;
Controls.Add(lblSeparator2);

hl = new HyperLink();

//continue with code from article
-- Robert Wallström, December 01, 2003
 
This code compiles fine (after fixing the typos is "seperator"), but when I try to run the aspx I get:

Parser Error
Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.

Parser Error Message: The directive is missing a 'assembly' attribute.

Source Error:


Line 1: <%@ Register TagPrefix="MyBar" Namespace="MyNavBar"%>


-- rob c, December 19, 2003
 
Did anyone find out a solution for this? I am also getting the following parser error.

An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.

Parser Error Message: The directive is missing a 'assembly' attribute.

Line 2: <%@ Register TagPrefix="MyBar" Namespace="MyNavBar" %>

Any ideas?

SJ
-- S J, May 16, 2004
 
The assembly is the name of the DLL that is generated and placed in the /bin folder when you compile the project. It is also usually the name of the project.
-- adam macy, September 01, 2004
 
Good Tutorial

However, I need help with reading in a custom control that has a collection from an aspx file. Any Help on that.

I currently have a control that write out its contents to an aspx file.

but when I attempt to read that file back in. I get a failure.


Parser Error Message: PWFTServerCtrl.FileEntryCollection must have items of type 'PWFTServerCtrl.FileEntry'. 'FileCollection' is of type 'System.Web.UI.HtmlControls.HtmlGenericControl'.

not sure exactly what I am missing.

I am using the standard CollectionEditor. Do I need to write my own?

Here is what my collection looks like in my code:

[
Browsable(true),
Description("List of Files."),
Category("Configuration"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerProperty),
EditorAttribute(typeof(System.ComponentModel.Design.CollectionEditor), typeof(System.Drawing.Design.UITypeEditor))
]
public FileEntryCollection FileCollection
{
get
{
return m_FileCollection;
}
set
{
this.m_FileCollection = value;
}
}

-- Robert Priest, January 06, 2005
 
Copyright © 2001 DevHood® All Rights Reserved