Click here to Skip to main content
Click here to Skip to main content

Graphical ASP.NET Controls

By , 11 Jul 2005
 
Prize winner in Competition "ASP.NET Sep 2004"

Graphical controls

Introduction

It is possible to create very nice web pages and you can even change the look of some form controls using CSS (for example, it is possible to change the look of textboxes and buttons), but there is no way to change the look of checkboxes and radio buttons. This article describes two custom controls with the same functionality as standard ASP.NET CheckBox and RadioButton and with properties that allow you to change the design of the controls using images. Another way of how to use controls like these is when you want to place an icon with checkbox functionality on your web page; for example, I wanted to mark some data as hidden, so I used checkbox control with lock and stricken lock icons.

These two controls are very simple to use, because all functionality is same as functionality of the standard controls, so if you want to replace the standard controls with these graphical controls, you can do it with Search/Replace tool. These controls use JavaScript, but it was tested with latest versions of IE, Opera and Mozilla (FireFox), so it should display correctly to majority of Internet users.

Another useful feature of the check box control is, that it supports three state. This can be very useful, because the standard HTML checkbox doesn't support a third state, so there is no way to create three state checkboxes in ASP.NET. If you want to allow a third state set ThreeState property to true. You will also need one or two (if you want to have a different image for active state) images. To get the state of a three state check box, you can use the CheckState property, which returns Checked, Unchecked or Indeterminate.

Background

Graphical checkbox control generates img tag, that is followed by span and hidden input control. The state of a control is saved in a hidden input control. When user clicks on image (or on text associated to checkbox), control changes its state (value of hidden control) and changes src attribute of the image element. (You can also set image that is displayed when user moves mouse over checkbox - this is done using onmouseover and onmouseout events.)

Graphical radio button is very similar to checkbox, but there is one complication: User should be able to check only one button in every group. Only solution to this problem is to use a bit more JavaScript. One JS function called radio{GroupName}Sel is generated for each group of controls (this is done using IsStartupScriptRegistered and RegisterStartupScript methods, so it is very simple to check if any control of the same group generated this function before). Each control in the group calls this function when it is clicked, so this function can uncheck the previously checked radio button.

Controls needs to implement interface IPostBackDataHandler to be able to read data after postback. This interface contains two methods. LoadPostData is called by ASP.NET after postback, and it processes postback data (reads data from POST collection and compares new value with the one stored in ViewState) and optionally calls second method (RaisePostDataChangedEvent) that raises the CheckedChanged event.

Using this control

Designer

Toolbox

Design time

Both controls support design-time, so you can simply add them to your page like any other ASP.NET controls. First, you'll need to add controls to the toolbox. To do this, right click on toolbox and select "Add/Remove Items". In "Customize Toolbox" dialog, click on Browse button and select EeekSoft.Web.Controls.dll. After clicking OK, you should be able to see two new controls in your toolbox.

You can modify properties in Properties window. Most important are properties that define location of images used by the control. After you enter image URL (CheckedImg or UncheckedImg), control will automatically update its look.

Code

Following code demonstrates how to access control properties from code:

<!-- Demo1.aspx -->
<%@ Register TagPrefix="cc1" Namespace="EeekSoft.Web.Controls"
  Assembly="EeekSoft.Web.Controls" %>
  
<cc1:graphicalcheckbox id="check1" runat="server" 
  CheckedOverImg="checked-over.gif" UncheckedOverImg="unchecked-over.gif" 
  UncheckedImg="unchecked.gif" CheckedImg="checked.gif" Checked="False" 
  Text="First checkbox"></cc1:graphicalcheckbox>
<cc1:graphicalcheckbox id="check1" runat="server" 
  CheckedOverImg="checked-over.gif" UncheckedOverImg="unchecked-over.gif" 
  UncheckedImg="unchecked.gif" CheckedImg="checked.gif" Checked="False" 
  Text="First checkbox"></cc1:graphicalcheckbox>
    
<asp:label id="lblInfo" runat="server" ></asp:label>
<asp:button id="btnPostback" runat="server" Text="Do postback!"></asp:button>
// Display what checkboxes are checked
private void btnPostback_Click(object sender, System.EventArgs e)
{
  if (check1.Checked&&check2.Checked)
    lblInfo.Text="Both checkboxes are checked!";
  else if (check1.Checked)
    lblInfo.Text="First checkbox is checked!";
  else if (check2.Checked)
    lblInfo.Text="Second checkbox is checked!";
  else 
    lblInfo.Text="No checkbox is checked!";
}

ThreeState chcekbox

As I described above, checkbox supports third state, so you can use it when you want to allow users to choose from three states (third state usually indicates that value can't be distinctly determined). Following code shows how to create a three state check box and how to get its state from code:

<!-- Demo2.aspx -->
<%@ Register TagPrefix="cc1" Namespace="EeekSoft.Web.Controls"
  Assembly="EeekSoft.Web.Controls" %>
  
<cc1:graphicalcheckbox id="threeCheck" runat="server"
  ThreeState="True" CheckState="Indeterminate" 
  IndeterminateOverImg="indet-over.gif" IndeterminateImg="indet.gif" 
  CheckedOverImg="checked-over.gif" UncheckedOverImg="unchecked-over.gif" 
  UncheckedImg="unchecked.gif" CheckedImg="checked.gif" 
  Text="Three state checkbox"></cc1:graphicalcheckbox>
    
<asp:label id="lblInfo" runat="server" ></asp:label>
<asp:button id="btnPostback" runat="server" Text="Do postback!"></asp:button>
// Display value of three state checkbox
private void btnPostback_Click(object sender, System.EventArgs e)
{
  switch(threeCheck.CheckState)
  {
    case CheckState.Checked:
      lblInfo.Text="Checkbox is checked!"; break;
    case CheckState.Unchecked:
      lblInfo.Text="Checkbox is unchecked!"; break;
    case CheckState.Indeterminated:
      lblInfo.Text="Value is set to indeterminated!"; break;
  }
}

Setting graphical look globally

Setting location of images for each state of control is a bit exhausting if you have more than one control on page, so I created an object called GraphicalControlsSettings that allows you to set location of images only once in the whole application. This object stores location of all images (both for checkbox and radio button) and is stored in the application state (Application property). After you save settings for controls using this object, all controls with property LoadGlobalSettings set to true will automatically load these settings, so you don't have to set location of particular images.

Following example shows how to use this object (to learn more, see design.aspx.cs file in demo application):

<!-- Demo3.aspx -->
<%@ Register TagPrefix="cc1" Namespace="EeekSoft.Web.Controls"
  Assembly="EeekSoft.Web.Controls" %>
  
<cc1:graphicalcheckbox LoadGlobalSettings="true" id="check1" 
  runat="server" Text="Checkbox 1"></cc1:graphicalcheckbox>
<cc1:graphicalcheckbox LoadGlobalSettings="true" id="check2" 
  runat="server" Text="Checkbox 2"></cc1:graphicalcheckbox>
// Demo3.aspx.cs
using EeekSoft.Web.Controls;

// Save checkbox settings in Page_Load or in Application_Start event handler
GraphicalControlsSettings grs=new GraphicalControlsSettings();
string skin="green/";

// Set images for chcekbox buttons
grs.CheckboxCheckedImg=skin+"check-checked.gif";
grs.CheckboxUncheckedImg=skin+"check.gif";
grs.CheckboxCheckedOverImg=skin+"check-checked-over.gif";
grs.CheckboxUncheckedOverImg=skin+"check-over.gif";

// Set images for radio buttons
grs.RadioCheckedImg=skin+"radio-checked.gif";
grs.RadioUncheckedImg=skin+"radio.gif";
grs.RadioCheckedOverImg=skin+"radio-checked-over.gif";
grs.RadioUncheckedOverImg=skin+"radio-over.gif";

// Save settings to Application
grs.Save();

History

  • 7/9/2005 - A few minor bugs fixed.

    (Thanks to Andreas Menges for his feedback.)

  • 10/12/2004 - Graphical check box now supports three state checkbox properties ThreeState, CheckState and images for third state added.

    (Thanks to bubák for this suggestion.)

  • 10/2/2004 - First version of article.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

About the Author

Tomas Petricek
Czech Republic Czech Republic
Member
I live in Prague, the capital city of Czech republic (most of the time Smile | :) ). I've been very interested in functional programming recently and I have a passion for the new Microsoft F# language. I'm writing a book about Functional Programming in the Real World that shows the ideas using examples in C# 3.0 and F#.
 
I've been Microsoft MVP (for C#) since 2004 and I'm one of the most active members of the F# community. I'm a computer science student at Charles University of Prague. My hobbies include photography, fractals and of course many things related to computers (except fixing them). My favorite book writers are Terry Pratchett and Philip K Dick and I like paintings by M. C. Escher.
 
PS: My favorite codeproject icon is Sheep | [baah] .

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralValidation of ControlsmemberPeter Maslin21 Dec '10 - 3:13 
hi
 
can anyone give any examples of how to validate this control (if possible)
 
thanks
 
Peter
GeneralValue not persisting when posting a pagememberMember 4583881 Apr '10 - 21:18 
Hello
 
I have downloaded your control and added it to one of my page.
When putting it directly on an .aspx page, it works fine
When posting back my page the value is still there, i.e the radio button remains checked when page displays
 
However i have to use it on an .ascx web control and this is where it is not working
 
Can you help out?
SuggestionRe: Value not persisting when posting a pagememberfflorez27 Aug '11 - 20:17 
I have the same problem and it is because the value stored on the variable "radio{0}" defined on the "Page.RegisterStartupScript("RadioButtonInit_"+group," script section is not persisted on the post back. I believe we need to use a second hidden input to store that value and get it from the ViewState of the control instead.
GeneralIssuememberSheetal198210 Jul '09 - 6:54 
If the value of radio button is checked from code behind i.e. checked true.. it stops working in wizard Control as well as ascx web user controls... does anybody have solution for this...?

Thank you OMG | :OMG:
QuestionLicense?memberAlexander Bender9 Jul '09 - 23:00 
Hello,
since nothing about it is mentioned in the article:
 
am i allowed to use your solution in a commercial (closed source) project?
QuestionError.membermedasatheesh27 May '09 - 6:28 
Hi,
 
Thanks for providing these lovely useful controls.
I am trying to add graphic radio button on my vb.net web page in code behind like this.
 
Dim rgraphic As New GraphicalRadioButton
rgraphic.ID = "Month Select"
cell.Controls.Add(rgraphic)
 
it showing the radio button, but when clicked it showing javascript error "tmp" is undefined. When I debugged I found that this controls page load event is not firing and so that its not creating tmp javascript variable.
 
Please help me in resolving this issue.
 
Thanks,
Satheesh M
GeneralHey any one knows how to use this control in gridview, oncheckedchanged event is not raisingmemberMember 378735231 Oct '08 - 10:30 
I am using this control in gridview but oncheckedchanged event is not raising.
Please let me know, if you know solution.
thanks in advance.
 
raju
GeneralError when adding control in code behindmembercoogee4 Jun '08 - 3:26 
Hi,
 
I am trying to use your fantastic control in code behind like this.
 
GraphicalRadioButton grRadio = new GraphicalRadioButton();
grRadio.ID = "test123";
 
TableCell rr = new TableCell();
rr.Controls.Add(grRadio);
 
Additionally I am using Master Pages.
 
I get the following error:
 
Server Error in '/CONNECTtoXerox' Application.
startIndex cannot be larger than length of string.
Parameter name: startIndex
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
 
Exception Details: System.ArgumentOutOfRangeException: startIndex cannot be larger than length of string.
Parameter name: startIndex
 
Source Error:
 
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
 
Stack Trace:
 
[ArgumentOutOfRangeException: startIndex cannot be larger than length of string.
Parameter name: startIndex]
System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy) +2916027
EeekSoft.Web.Controls.GraphicalRadioButton.Render(HtmlTextWriter output) +332
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +25
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +121
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +22
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +199
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +20
System.Web.UI.WebControls.TableCell.RenderContents(HtmlTextWriter writer) +97
System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) +29
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +25
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +121
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +22
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +199
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +20
System.Web.UI.WebControls.WebControl.RenderContents(HtmlTextWriter writer) +7
System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) +29
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +25
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +121
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +22
System.Web.UI.WebControls.Table.RenderContents(HtmlTextWriter writer) +536
System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) +29
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +25
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +121
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +22
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +199
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +20
System.Web.UI.WebControls.WebControl.RenderContents(HtmlTextWriter writer) +7
System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) +29
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +25
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +121
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +22
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +199
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +20
System.Web.UI.WebControls.TableCell.RenderContents(HtmlTextWriter writer) +97
System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) +29
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +25
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +121
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +22
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +199
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +20
System.Web.UI.WebControls.WebControl.RenderContents(HtmlTextWriter writer) +7
System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) +29
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +25
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +121
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +22
System.Web.UI.WebControls.Table.RenderContents(HtmlTextWriter writer) +536
System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) +29
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +25
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +121
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +22
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +199
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +20
System.Web.UI.WebControls.WebControl.RenderContents(HtmlTextWriter writer) +7
System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) +29
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +25
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +121
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +22
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +199
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +20
System.Web.UI.HtmlControls.HtmlForm.RenderChildren(HtmlTextWriter writer) +59
System.Web.UI.HtmlControls.HtmlForm.Render(HtmlTextWriter output) +68
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +25
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +121
System.Web.UI.HtmlControls.HtmlForm.RenderControl(HtmlTextWriter writer) +37
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +199
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +20
System.Web.UI.Control.Render(HtmlTextWriter writer) +7
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +25
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +121
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +22
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +199
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +20
System.Web.UI.Page.Render(HtmlTextWriter writer) +26
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +25
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +121
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +22
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2558
GeneralRe: Error when adding control in code behindmemberernest_elias2 Sep '08 - 7:12 
Hi,
change EeekSoft.Web.Controls\GraphicalRadioButton.cs to this
 
233 string tmp=Regex.Match(sb.ToString(),@"style=\""[^\""]*\""").Value;
234 if (!string.IsNullOrEmpty(tmp) && tmp.Length >=8)
235 st+=tmp.Substring(7,tmp.Length-8);
 
however when I want to use control like this
 
<eeek:graphicalradiobutton runat="server" id="btn" checked="false" checkedimg="../gfx/img1.bmp" uncheckedimg="../gfx/img2.bmp" text="aj" xmlns:eeek="#unknown" />
 
it doesn't work Frown | :(
 
-ernest

GeneralRe: Error when adding control in code behindmemberernest_elias2 Sep '08 - 20:47 
Hi,
yes it works, I found the bug, its my fault
the proposed update is fine
have nice GUI
 
-ernest

General.Net 2.0 Master pagesmembergraham.lock26 Nov '07 - 3:17 
Hi,
 
These controls look really useful but I'm trying to get them to work in .Net 2.0 master pages where there appears to be a viewstate problem as the check state is not surving postback. Any ideas?
 
GDL
GeneralRe: .Net 2.0 Master pagesmembercoogee4 Jun '08 - 6:22 
I have the same problem.
 
Is there a solution to this?
 
Mirco
QuestionJavascript error when using with Ajax updatepanelmemberFranzS66819 Oct '07 - 5:21 
I'm trying to get the radiobuttons to work inside an Ajax Updatepanel, but after every callback i get a js error 'null' is null or not an object
 
Is there anyway to get these controls to work inside an updatepanel?
 

 

 

GeneralProblem in designmode when globalsettings are usedmemberroecki16 Sep '07 - 1:01 
There is an exception thrown in designmode when global settings are used.
 
In designmode HttpContext.Current is null. In GraphicalControlsSettings.Load this must be checked in order to avoid this error.
 
Anton
 

Generalvery nice workmemberpeter gabris7 Sep '07 - 8:10 
A pleasure to read, the paper and the code as well Tomasi!
Generaladding Graphical Radio button with Rich listmemberRajesh.N.V5 Nov '06 - 19:26 

I am beginer of Asp.net and C# I want to combine two code written in this forum the Codes are "Graphical Radio Button and Rich List" the url of those two are
1> /aspnet/graphicalcontrols.asp
2> /aspnet/RichListControls.asp
 
Thanks in advance
 
Regards
Rajesh.N.V
QuestionPosition popup relative to a control on the pagememberdjlandino15 Oct '06 - 2:28 
Hi,
I was wondering if there was an easy way to position the popup relative to a specified control on the page. For example, I would like it to appear 20px down and 20px to the right of a button I have on my page. Any help would be greatly appreciated. The is a great little control!
GeneralError about startIndex after importing dllmemberjusmeig3 Aug '06 - 3:14 
Hi there,
 
I imported the dll and added the controls to VS 2005. I added a control (if I checkbox or radiobutton) I get the error below:
 
startIndex cannot be larger than length of string.
Parameter name: startIndex
 
Any ideas? I've touched nothing Smile | :)
 
Cheers,
 
Justin.
GeneralRe: Error about startIndex after importing dllmembermohd_osman9 Aug '06 - 7:11 
I get the same errors
AnswerRe: Error about startIndex after importing dllmemberncanen26 Oct '06 - 12:04 
I had the same problem, but found that when I resize the control it goes away.
AnswerRe: Error about startIndex after importing dllmembervlad.pitaru8 Nov '06 - 1:39 
Add this to your graphical checkbox:
Font-Size="100%"
 
It should look like this:
<inc:GraphicalCheckBox ID="GraphicalCheckBox1" runat="server" ThreeState="True" Font-Size="100%">
QuestionHow to inherit this control to Checkboxlist or radiobuttonlistmemberwonderJAM1 Jul '06 - 4:14 
this is great!!
 
But, how to inherit this control to Checkboxlist or radiobuttonlist but without using a datalist control?
 
Thanks..
Generaljavascript eventsmemberjuantek14 Jan '06 - 18:30 
if you use the onclick event to swap images then what javascript event is left to do validation?, I have in a form 10 checkboxes but 2 of them cannot be selected together unless a specific checkbox has been previously checked (so radiobuttons are out of the question) so I use the onclick event to check this using a javascript function that generates an alert. Posting back is out of the question. I cannot get that to work with your control. Any suggestions?
GeneralRe: javascript eventsmemberHenrik Bergstrom13 Nov '09 - 0:39 
I hade the same problem. I have a price calculator that is written in javascript.
No postback.
I added a new attribute "onClientClick" that adds a custom javafuction to call after the existing onClick code is done. Then I can call my own function.
 
I also had problem with image path in masterpages and url-rewriting so I added ResolveUrl() on all image attribute to get the correct path to the image.
 
//Henrik
QuestionAdd Controls at runtime (CodeBehind) ?memberHappy Hippo12 Dec '05 - 2:00 
I am building WebForms dynamically at runtime like below:
 
EeekSoft.Web.Controls.GraphicalCheckBox checkbox = new EeekSoft.Web.Controls.GraphicalCheckBox();
...
Properties
...
Controls.Add(checkbox);
 
But nothing happens. Everything is correctly prepared.
 
Does anyone know why?
 
Thanks

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 12 Jul 2005
Article Copyright 2004 by Tomas Petricek
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid