Sunday, October 25, 2009

Autocomplete textbox in C#

Here is the code to develop auto complete text box.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
private void Form1_Load(object sender, EventArgs e)
{
AutoCompleteStringCollection autolist = new AutoCompleteStringCollection();
SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True");
con.Open();

SqlCommand comm = new SqlCommand("select * from users", con);
SqlDataAdapter da = new SqlDataAdapter(comm);

DataTable dt = new DataTable();
da.Fill(dt);
foreach (DataRow r in dt.Rows)
{
autolist.Add(r[0].ToString());
}
textBox1.AutoCompleteMode = AutoCompleteMode.Suggest;
textBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
textBox1.AutoCompleteCustomSource = autolist;
}

Wednesday, October 21, 2009

DateTime Format String

DateTime has its own set format string modifiers because there are so many ways to display a date and time.

Standard Format String

This is basically built in short hand for custom format string. You pass in the one character string to denote which custom format you want.

i.e.
now.ToString("d"); // "10/21/2009"
now.ToString("D"); // "Wednesday, October 21, 2009"
now.ToString("G"); // "10/21/2009 10:16:01 PM"


Custom Format String
Custom format string gives you the flexibility to build your own formatting. When using a single character format string specifier, you will need to prepend it with a "%", otherwise it will be interpreted as a Standard Format String. Here are the basics for building your own string:

Example:
StringBuilder strBuilder=new StringBuilder ();
DateTime now = new DateTime(2009,10, 21, 22, 16, 01, 08, DateTimeKind.Local);
strBuilder.AppendLine ("now.ToString() ==> " + now .ToString() );
strBuilder.AppendLine("now.ToString(\"d\")" + now.ToString("d"));
strBuilder.AppendLine("now.ToString(\"D\")" + now.ToString("D"));
strBuilder.AppendLine("now.ToString(\"G\")" + now.ToString("G"));

// Year
strBuilder.AppendLine("YEAR ");
strBuilder.AppendLine ("now.ToString(\"%y\") ==> " + now.ToString("%y") );
strBuilder.AppendLine ("now.ToString(\"yy\") ==> " + now.ToString("yy") );
strBuilder.AppendLine ("now.ToString(\"yyy\") ==>" + now.ToString("yyy") );
strBuilder.AppendLine ("now.ToString(\"yyyy\") ==>" + now.ToString("yyyy") );

//Month
strBuilder.AppendLine("MONTH ");
strBuilder.AppendLine ("now.ToString(\"%M\") ==> " + now.ToString("%M") );
strBuilder.AppendLine ("now.ToString(\"MM\") ==> " + now.ToString("MM") );
strBuilder.AppendLine ("now.ToString(\"MMM\") ==>" + now.ToString("MMM") );
strBuilder.AppendLine("now.ToString(\"MMMM\") ==>" + now.ToString("MMMM"));


//Day
strBuilder.AppendLine("Day ");
strBuilder.AppendLine("now.ToString(\"%d\") ==> " + now.ToString("%d"));
strBuilder.AppendLine("now.ToString(\"dd\") ==> " + now.ToString("dd"));
strBuilder.AppendLine("now.ToString(\"ddd\") ==>" + now.ToString("ddd"));
strBuilder.AppendLine("now.ToString(\"dddd\") ==>" + now.ToString("dddd"));

//Hour
strBuilder.AppendLine("HOUR ");
strBuilder.AppendLine("now.ToString(\"%h\") ==> " + now.ToString("%h"));
strBuilder.AppendLine("now.ToString(\"hh\") ==> " + now.ToString("hh"));
strBuilder.AppendLine("now.ToString(\"hhh\") ==>" + now.ToString("hhh"));
strBuilder.AppendLine("now.ToString(\"hhhh\") ==>" + now.ToString("hhhh"));
strBuilder.AppendLine("now.ToString(\"%H\") ==> " + now.ToString("%H"));
strBuilder.AppendLine("now.ToString(\"HH\") ==> " + now.ToString("HH"));
strBuilder.AppendLine("now.ToString(\"HHH\") ==>" + now.ToString("HHH"));
strBuilder.AppendLine("now.ToString(\"HHHH\") ==>" + now.ToString("HHHH"));

//Minutes
strBuilder.AppendLine("MINUTES ");
strBuilder.AppendLine("now.ToString(\"%m\") ==> " + now.ToString("%m"));
strBuilder.AppendLine("now.ToString(\"mm\") ==> " + now.ToString("mm"));
strBuilder.AppendLine("now.ToString(\"mmm\") ==>" + now.ToString("mmm"));
strBuilder.AppendLine("now.ToString(\"mmmm\") ==>" + now.ToString("mmmm"));

//Seconds
strBuilder.AppendLine("SECONDS ");
strBuilder.AppendLine("now.ToString(\"%s\") ==> " + now.ToString("%s"));
strBuilder.AppendLine("now.ToString(\"ss\") ==> " + now.ToString("ss"));
strBuilder.AppendLine("now.ToString(\"sss\") ==>" + now.ToString("sss"));
strBuilder.AppendLine("now.ToString(\"ssss\") ==>" + now.ToString("ssss"));

//Milliseconds
strBuilder.AppendLine("MILLISECONDS ");
strBuilder.AppendLine("now.ToString(\"%f\") ==> " + now.ToString("%f"));
strBuilder.AppendLine("now.ToString(\"ff\") ==> " + now.ToString("ff"));
strBuilder.AppendLine("now.ToString(\"fff\") ==>" + now.ToString("fff"));
strBuilder.AppendLine("now.ToString(\"ffff\") ==>" + now.ToString("ffff"));
strBuilder.AppendLine("now.ToString(\"%F\") ==> " + now.ToString("%F"));
strBuilder.AppendLine("now.ToString(\"FF\") ==> " + now.ToString("FF"));
strBuilder.AppendLine("now.ToString(\"FFF\") ==>" + now.ToString("FFF"));
strBuilder.AppendLine("now.ToString(\"FFFF\") ==>" + now.ToString("FFFF"));

//Kind
strBuilder.AppendLine("KIND ");
strBuilder.AppendLine("now.ToString(\"%K\") ==> " + now.ToString("%K"));
strBuilder.AppendLine("now.ToString(\"KK\") ==> " + now.ToString("KK"));
strBuilder.AppendLine("now.ToString(\"KKK\") ==>" + now.ToString("KKK"));
strBuilder.AppendLine("now.ToString(\"KKKK\") ==>" + now.ToString("KKKK"));

//TimeZone
strBuilder.AppendLine("TIMEZONE ");
strBuilder.AppendLine("now.ToString(\"%z\") ==> " + now.ToString("%z"));
strBuilder.AppendLine("now.ToString(\"zz\") ==> " + now.ToString("zz"));
strBuilder.AppendLine("now.ToString(\"zzz\") ==>" + now.ToString("zzz"));
strBuilder.AppendLine("now.ToString(\"zzzz\") ==>" + now.ToString("zzzz"));

//Other
strBuilder.AppendLine("OTHER ");
strBuilder.AppendLine("now.ToString(\"%g\") ==> " + now.ToString("%g"));
strBuilder.AppendLine("now.ToString(\"gg\") ==> " + now.ToString("gg"));
strBuilder.AppendLine("now.ToString(\"ggg\") ==>" + now.ToString("ggg"));
strBuilder.AppendLine("now.ToString(\"gggg\") ==>" + now.ToString("gggg"));

strBuilder.AppendLine("now.ToString(\"%t\") ==> " + now.ToString("%t"));
strBuilder.AppendLine("now.ToString(\"tt\") ==> " + now.ToString("tt"));
strBuilder.AppendLine("now.ToString(\"ttt\") ==>" + now.ToString("ttt"));
strBuilder.AppendLine("now.ToString(\"tttt\") ==>" + now.ToString("tttt"));

textBox1.Text = strBuilder.ToString();


Output:

now.ToString() ==> 10/21/2009 10:16:01 PM
now.ToString("d")10/21/2009
now.ToString("D")Wednesday, October 21, 2009
now.ToString("G")10/21/2009 10:16:01 PM
YEAR
now.ToString("%y") ==> 9
now.ToString("yy") ==> 09
now.ToString("yyy") ==>2009
now.ToString("yyyy") ==>2009
MONTH
now.ToString("%M") ==> 10
now.ToString("MM") ==> 10
now.ToString("MMM") ==>Oct
now.ToString("MMMM") ==>October
Day
now.ToString("%d") ==> 21
now.ToString("dd") ==> 21
now.ToString("ddd") ==>Wed
now.ToString("dddd") ==>Wednesday
HOUR
now.ToString("%h") ==> 10
now.ToString("hh") ==> 10
now.ToString("hhh") ==>10
now.ToString("hhhh") ==>10
now.ToString("%H") ==> 22
now.ToString("HH") ==> 22
now.ToString("HHH") ==>22
now.ToString("HHHH") ==>22
MINUTES
now.ToString("%m") ==> 16
now.ToString("mm") ==> 16
now.ToString("mmm") ==>16
now.ToString("mmmm") ==>16
SECONDS
now.ToString("%s") ==> 1
now.ToString("ss") ==> 01
now.ToString("sss") ==>01
now.ToString("ssss") ==>01
MILLISECONDS
now.ToString("%f") ==> 0
now.ToString("ff") ==> 00
now.ToString("fff") ==>008
now.ToString("ffff") ==>0080
now.ToString("%F") ==>
now.ToString("FF") ==>
now.ToString("FFF") ==>008
now.ToString("FFFF") ==>008
KIND
now.ToString("%K") ==> +05:00
now.ToString("KK") ==> +05:00+05:00
now.ToString("KKK") ==>+05:00+05:00+05:00
now.ToString("KKKK") ==>+05:00+05:00+05:00+05:00
TIMEZONE
now.ToString("%z") ==> +5
now.ToString("zz") ==> +05
now.ToString("zzz") ==>+05:00
now.ToString("zzzz") ==>+05:00
OTHER
now.ToString("%g") ==> A.D.
now.ToString("gg") ==> A.D.
now.ToString("ggg") ==>A.D.
now.ToString("gggg") ==>A.D.
now.ToString("%t") ==> P
now.ToString("tt") ==> PM
now.ToString("ttt") ==>PM
now.ToString("tttt") ==>PM

How to get string in Title case

Here is the code example for converting the string to title case.

//initialize the datetime object with today's date
DateTime todaysDate = DateTime.Now;

//get the current culture
CultureInfo properCase = System.Threading.Thread.CurrentThread.CurrentCulture;

//get text info object from the current culture
TextInfo textInfoObject = properCase.TextInfo;

//the textinfo ToTitleCase method will return the text in title case
MessageBox.Show(textInfoObject.ToTitleCase(todaysDate.ToString("MMMM")));



Output:

October

Here, the todaysDate.ToString("MMMM") prints the complete month like October, December etc.

Friday, August 14, 2009

Programmatically setting Master Page

The MasterPage class derives from UserControl. The master page will inject itself as the top control in a page’s control hierarchy by clearing the page’s Controls array and adding itself to into the collection. Doing so includes all of the markup and controls defined inside the master page in the page's control tree. The master page can then walk the Content controls that existed in the web form and bring them back them into the control hierarchy in the appropriate locations. The master page injection happens after the PreInit event fires for a Page object, but before the Init event fires.

We can use the @ Page directive and the web.config to specify master page files for our web forms, but sometimes we want to set the master page programatically. A page’s MasterPageFile property sets the master page for the content page to use. This property must be set in the PreInit event (or earlier), like the code below. One the master page has injected itself into the control hierarchy it is too late to try to set a new master page for the web form. If you try to set the MasterPageFile property after the PreInit event fires, the runtime will throw an InvalidOperationException.


Protected Sub Page_PreInit(ByVal sender As Object, _
ByVal e As EventArgs) _
Handles Me.PreInit
' we can select a different master page in the PreInit event
Me.MasterPageFile = "~/otherMasterPage.master"
End Sub


Another way to interact with a master page is through the Master property of a page object. Let’s say we need to get to the Footer property defined in our master page. There are two approaches to touching this property. The first is to use the Master property of the System.Web.UI.Page class, which returns a MasterPage reference. In order to get to the Footer property, though, we would have to cast the reference to our derived master page type, like the following code.
CType(Master, otherMasterPage).FooterText = "New Footer Text"


A second approach, if you know the exact master page file your page will be using at runtime, is to let the ASP.NET page parser generate a strongly typed Master property by adding an @ MasterType directive to your ASPX file, as shown below.
<%@ MasterType VirtualPath="~/myMasterPage.master" %>


The MasterType directive will instruct the runtime to add a new Master property to code-generated file for the page. The new property will return a reference matching the MasterType. With a MasterType directive in place for our web form, we don't need a cast.

Master Pages Events

Another master page twist that catches developers off guard is the order of the page lifecycle events. Let’s say we write the following code in our web form:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Response.Write("Hello from Page_Load in default.aspx ")
End Sub


.. and the following code in our master page:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Response.Write("Hello from Page_Load in Master1.master")
End Sub


Pop quiz: which Response.Write will appear in the output first?
Hint: most ASP.NET events are raised starting at the top of the control tree and working downward.
In this case, “Hello from Page_Load in default.aspx” will appear before “Hello from Page_Load in Master1.master”, because the content page’s Load event fires before the master page’s Load event.

Let’s set up another quiz using the following code in our content page.

Protected Sub Page_Init(ByVal sender As Object,ByVal e As System.EventArgs)
Response.Write("Hello from Page_Init in default.aspx")
End Sub


... and the following code in our master page.

Protected Sub Page_Init(ByVal sender As Object,ByVal e As System.EventArgs)
Response.Write("Hello from Page_Init in Master1.master")
End Sub


Pop quiz: which Init event will fire first?

Earlier we said most ASP.NET events work their way down the tree of controls. The truth is all lifecycle events (Load, PreRender, etc.) work in this fashion except the Init event. The initialization event works from the inside out. Since the master page is inside the content page, the master page’s Init event handler will fire before the content page’s Init event handler.

Obviously, problems will occur if the content page’s Load event handler depends on the master page's Load event to finish some work or initialize a reference. If you find yourself with this problem, or are worried about the order of events when a master page is involved, you might be too tightly coupled to the master page. Consider our earlier approach of using a custom event when when something interesting happens in the master page, and let the content page subscribe to the event and take action. This approach achieves greater flexibility.

Master Pages

Master pages in ASP.NET are the key to building a professional web application with a consistent, easy to maintain layout.

A professional web site will have a standardized look across all pages. For example, one popular layout type places a navigation menu on the left side of the page, a copyright on the bottom, and content in the middle. It can be difficult to maintain a standard look if you must always put the common pieces in place with every web form you build. In ASP.NET 2.0, master pages will make the job easier. You’ll only need to write the common pieces once - in the master page. A master page can serve as a template for one or more web forms. Each ASPX web form only needs to define the content unique to itself, and this content will plug into specified areas of the master page layout.

Example Master Pages:

To add a master page to a web project, right-click your web project in the Solution Explorer window, select Add New Item, and select the Master Page item type from the Add New Item dialog. The listing below shows a sample master page in source view.


<%@ Master Language="VB" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>


A master page looks very similar to an ASPX file, except a master page will have a .master file extension instead of a .aspx extension, and uses an @ Master directive instead of an @ Page directive at the top. Master pages will define the <html>, <head>, <body> , and <form> tags. A new control, the ContentPlaceHolder control also appears in our master page. You can have one or more ContentPlaceHolder controls in a master page. ContentPlaceHolder controls are where we want our ASPX web forms to place their content.
Let’s also write a simple web form to use our master page.


<%@ Page Language="VB" MasterPageFile="~/Master1.master"
AutoEventWireup="true" Title="Untitled Page" %>
<asp:Content ID="Content1" Runat="Server"
ContentPlaceHolderID="ContentPlaceHolder1" >
<asp:Label ID="Label1" runat="server" Text="Hello, World"/>
</asp:Content>



Just like any ASPX form, our master page can contain code in a <script> block, or in a code-behind file, and can respond to page lifecycle events. The MasterPage class (from the System.Web.UI namespace) derives from UserControl and will have all of the usual events: Init, Load, PreRender, etc.

The web form contains a single Content control, which in turn is the proud parent of a Label. At this point, the page and master page are two separate objects, each with their own children. When it comes time for the master page to do its job, the master page replaces the page’s children with itself.

The master page’s next step is to look for Content controls in the controls formerly associated with the page. When the master page finds a Content control that matches a ContentPlaceHolder, it moves the controls into the matching ContentPlaceHolder. In our simple setup, the master page will find a match for ContentPlaceHolder1, and copy over the Label.

All of this work occurs after the content page’s PreInit event, but before the content page’s Init event. During this brief slice of time, the master page is deserving of its name. The master page is in control - giving orders and rearranging controls. However, by the time the Init event fires the master page becomes just another child control inside the page. In fact, the MasterPage class derives from the UserControl class.

Of Headers and Meta tags

The master page must define <head>,meaning the master page will include the <title> tag, among others. Since the master page does not know the title of the content page that will plug in, it simply sets the title to “untitled”.
Since a content page cannot contain any markup outside of Content controls, there is no way for a content page to use a title tag, but there is now a Title attribute in the @ Page directive. There is also a Title property on the page itself.
For other elements that end up in the header, the Page class now exposes a Header property of type HtmlHead. You can use the HtmlHead reference to modify style sheet settings and add HtmlMeta objects as needed.

Conclusions

Master pages provide a key component to any web application, namely the ability to organize a consistent layout into reusable templates. These master page templates offer full designer support and programmatic interfaces to meet the demands of most applications.

Saturday, August 8, 2009

The extern modifier C# Reference

The extern modifier is used to declare a method that is implemented externally. A common use of the extern modifier is with the DllImport attribute when using Interop services to call into unmanaged code; in this case, the method must also be declared as static, as shown in the following example:

[DllImport("avifil32.dll")]
private static extern void AVIFileInit();


It is an error to use the abstract (C# Reference) and extern modifiers together to modify the same member. Using the extern modifier means that the method is implemented outside the C# code, while using the abstract modifier means that the method implementation is not provided in the class.

Example

In this example, the program receives a string from the user and displays it inside a message box. The program uses the MessageBox method imported from the User32.dll library.

using System;
using System.Runtime.InteropServices;
class MainClass
{
[DllImport("User32.dll")]
public static extern int MessageBox(int h, string m, string c, int type);

static int Main()
{
string myString;
Console.Write("Enter your message: ");
myString = Console.ReadLine();
return MessageBox(0, myString, "My Message Box", 0);
}
}


This example creates a DLL from a C program that is invoked from within the C# program in the next example.

// cmdll.c
// compile with: /LD
int __declspec(dllexport) SampleMethod(int i)
{
return i*10;
}


This example uses two files, CM.cs and Cmdll.c, to demonstrate extern. The C file is the external DLL created in Example 2 that is invoked from within the C# program.

// cm.cs
using System;
using System.Runtime.InteropServices;
public class MainClass
{
[DllImport("Cmdll.dll")]
public static extern int SampleMethod(int x);

static void Main()
{
Console.WriteLine("SampleMethod() returns {0}.", SampleMethod(5));
}
}


Output

SampleMethod() returns 50.


Remarks

To build the project:

* Compile Cmdll.c to a DLL using the Visual C++ command line:

cl /LD Cmdll.c

* Compile CM.cs using the command line:

csc CM.cs

This will create the executable file CM.exe. When you run this program, SampleMethod will pass the value 5 to the DLL file, which returns the value multiplied by 10.

Note
The extern keyword also can define an external assembly alias, making it possible to reference different versions of the same component from within a single assembly. For more information, see extern alias (C# Reference).

The extern keyword is more limited in use than in C++. To compare with the C++ keyword, see Using extern to Specify Linkage in the C++ Language Reference.

IIf Function

Returns one of two objects, depending on the evaluation of an expression.

Public Function IIf( _
ByVal Expression As Boolean, _
ByVal TruePart As Object, _
ByVal FalsePart As Object _
) As Object


Parameters

Expression

Required. Boolean. The expression you want to evaluate.

TruePart

Required. Object. Returned if Expression evaluates to True.

FalsePart

Required. Object. Returned if Expression evaluates to False.


Remarks

The IIf function provides a counterpart for the ternary Conditional Operator: ? : in Visual C++.

Example

This example uses the IIf function to evaluate the testMe parameter of the checkIt procedure and returns the word "Large" if the amount is greater than 1000; otherwise, it returns the word "Small".
Visual Basic

Function checkIt(ByVal testMe As Integer) As String
Return CStr(IIf(testMe > 1000, "Large", "Small"))
End Function


Note that if Option Strict is On, you must use the CStr keyword to explicitly convert the return from Object to String.

?: Operator

The conditional operator (?:) returns one of two values depending on the value of a Boolean expression. The conditional operator is of the form.
condition ? first_expression : second_expression;


If condition is true, first expression is evaluated and becomes the result; if false, the second expression is evaluated and becomes the result. Only one of two expressions is ever evaluated.

Calculations that might otherwise require an if-else construction can be expressed more concisely and elegantly with the conditional operator. For example, to avoid a division by zero in the calculation of the sin function you could write either

if(x != 0.0) s = Math.Sin(x)/x; else s = 1.0;


or, using the conditional operator,

s = x != 0.0 ? Math.Sin(x)/x : 1.0;


The conditional operator is right-associative, so an expression of the form

a ? b : c ? d : e


is evaluated as

a ? b : (c ? d : e)


not

(a ? b : c) ? d : e


The conditional operator cannot be overloaded.

Example

// cs_operator_conditional.cs
using System;
class MainClass
{
static double sinc(double x)
{
return x != 0.0 ? Math.Sin(x)/x : 1.0;
}

static void Main()
{
Console.WriteLine(sinc(0.2));
Console.WriteLine(sinc(0.1));
Console.WriteLine(sinc(0.0));
}
}



Output

0.993346653975306
0.998334166468282
1

Friday, July 31, 2009

How to get uploaded image dimensions in asp.net

If you want to know the image dimension you can get the dimensions by using the following code snippet by providing the image path to the method:

public string getImageDimensions(string strPath)
{
System.Drawing.Image imgFromFile= System.Drawing.Image.FromFile(strPath);
float imgWidth = imgFromFile.PhysicalDimension.Width;
float imgHeight = imgFromFile.PhysicalDimension.Height;
string size= imgWidth.toString()+","+imgHeight.toString();
return size;
}

Where,
strPath is the path of the file.

Similary we can get the get uploaded image dimensions as follows:

public string getImageDimensions(Stream streamImgFile)
{
System.Drawing.Image imgFromStream= System.Drawing.Image.FromStream(streamImgFile);
float imgWidth = imgFromStream.PhysicalDimension.Width;
float imgHeight = imgFromStream.PhysicalDimension.Height;
string size= imgWidth.toString()+","+imgHeight.toString();
return size;
}


For e.g.here in the following code imgUploader is name of asp.net file uploader control:

string strImgUploadedType = imgUploader.PostedFile.ContentType.ToString().ToLower();
string strImUploadedFileName = imgUploader.PostedFile.FileName;

//get Dimensions from stream
string strDim= getImageDimensions(imgUploader.PostedFile.InputStream);
//Or we can use from file
string strDim= getImageDimensions(imgUploader.PostedFile.FileName);

string[] strDimArr= s.Split(',');

Response.Write( "Image Width:" + strDimArr[0]+ “
”);
Response.Write("Image Height:" + strDimArr[1]+ “
”);


The PostedFile property will contain a valid System.Web.HttpPostedFile object if file indeed was uploaded. HttpPostedFile provides us with 4 properties:

* ContentLength: size of uploaded file in bytes
* ContentType: MIME type of uploaded file, i.e. "image/gif"
* FileName: full path to uploaded file on client's system, i.e.c:\Bin\Img1.gif
* InputStream: stream object that gives us access to uploaded data

Wednesday, July 22, 2009

Adding Client-Side Script from the Code-Behind Class

All ASP.NET Web pages must be derived directly or indirectly from the Page class in the System.Web.UI namespace. The Page class contains the base set of methods, properties, and events required for a functioning Web page. Among the class's many methods are a few methods designed for injecting client-side script into the rendered HTML. These methods are called from the code-behind class and can therefore be used to emit data-driven client-side script. The pertinent Page class methods for emitting client-side script follow.

The base class is derived from the System.Web.UI.Page class, so you can access the Page class's public methods by calling them directly from your code-behind class.
Note To access the Page class's methods, you can either type in the method name directly, or utilize IntelliSense in Microsoft Visual Studio .NET by entering MyBase. (for Microsoft Visual Basic .NET), this. (for C#), or Page. (for either C# or Visual Basic .NET). If you are using Visual Basic .NET as your programming language of choice, be sure to configure Visual Studio .NET to not hide advanced members, or you won't see these client-side script methods. (To show advanced members, go to Tools | Options | Text Editor | Basic and uncheck Hide advanced members.)

RegisterClientScriptBlock(key, script)

The RegisterClientScriptBlock method adds a block of client-side script after the Web Form's rendered form element, before any Web controls contained within the Web Form. The key input parameter allows you to specify a unique key associated with this script block, whereas the script parameter includes the complete script code to emit. (This script parameter should include the actual script element, along with the client-side JavaScript or Microsoft VBScript.)

When emitting client-side script through the code-behind class of an ASP.NET Web page, typically the value of the key parameter isn't of paramount importance. Simply choose a descriptive key value. The key parameter is more pertinent when injecting client-side script code through a custom, compiled server control. There may be instances where a compiled control requires that there be a set of client-side functions. Multiple instances of the server control on one page might be able to share these common client-side script functions, so these functions need only be emitted once for the entire page, and not once per control instance. For example, the validation controls utilize client-side code to enhance the user experience. This client-side code must be present if there are any validation controls on the page, but if there are multiple validation controls, all can use this single set of shared functions.
By giving a script block a key, a control developer building a control that utilizes a set of common client-side functions can check to see if the required set of common functions has already been added by another instance of the control on the page. If so, it need not re-add the common script. To check if a script block has been added with the same key, use the IsClientScriptBlockRegistered(key) method, which will return a Boolean value indicating whether or not a script block with the same key has been registered. Realize that you can add a script block without first checking if it's registered. If you attempt to add a script block with a key that's already registered, the added script block will be ignored and the original script block will remain assigned to that key.

Note The IsClientScriptBlockRegistered method is particularly useful in two situations. First, it comes in handy when you're adding similar, but unique script blocks, and you need to insure that each script block is given a unique key. The code we'll examine later on in this article illustrates the utility of the "is registered" method. A second use is when building a control that needs some common script, especially if the script is not trivially generated. By using the IsClientScriptBlockRegistered method, you can ensure that the script common to all instances of the server control on the page is generated only once per page load, rather than once per control instance on the page.


The RegisterClientScriptBlock method is useful for adding client-side script that does not rely on any of the form fields present within the Web Form. A common use of this method is to display a client-side alert box. For example, imagine that you had a Web page with some TextBox Web controls and a Save Button. The TextBox controls might have particular values from a database. Imagine that this page allowed the user to modify these values and commit their changes by clicking the Save button. When clicking Save, the Web page would be posted back, and the Button's Click event would fire. You could create a server-side event handler for this event that updates the database. To let the user know that their changes had been saved, you might want to display an alert box that says, "Your changes have been saved." This could be accomplished by adding the following line of code to the Button's Click event handler:


The above will add the specified script content within the page's form, but before the content within the form. When the page is rendered in the user's browser they will see a client-side alert box displayed upon page load.



Note One potentially undesirable side effect of the above example is that the alert box will be displayed right after the browser received the form tag. The browser will suspend rendering of the Web page until the user clicks the alert box's OK button. This means that the user will see a white browser page until they click OK. If you want to have the page displayed completely before displaying the alert box, you can have the JavaScript inserted at the end of the form element using the RegisterStartupScript method, which we'll discuss next.


RegisterStartupScript(key, script)
The RegisterStartupScript method is quite similar to the RegisterClientScriptBlock method. The main difference is the location where the client-side script is emitted. Recall that with the RegisterClientScriptBlock the script is emitted after the start of the form element, but before the form's contents. RegisterStartupScript, on the other hand, adds the specified script at the end of the form, after all form fields. Use RegisterStartupScript to place client-side script that interacts with the rendered HTML elements. (Later we'll look at an example of setting the focus to a form field upon page load; to accomplish this you'll use the RegisterStartupScript method.)
Like RegisterClientScriptBlock, the script blocks added by RegisterStartupScript need a unique key value. Again, this key value is primarily used by custom control developers. Not surprisingly, there is an IsStartupScriptRegistered(key) method as well, which returns a Boolean value indicating if a script block with the specified key has already been registered or not.
Note For more information on using RegisterStartupScript and RegisterClientScriptBlock in creating custom, compiled server controls, read an earlier article of mine: Injecting Client-Side Script from an ASP.NET Server Control.


RegisterArrayDeclaration(arrayName, arrayValue)
If you need to create a client-side JavaScript Array object with some set values, use this method to add a value to a specific array. For example, when using validation controls in an ASP.NET Web page, an Array object (Page_Validators) is built that contains references to the set of validation controls on the page. When the form is submitted, this array is enumerated to check if the various validation controls are valid or not.
To add the values 1, 2, and 3 to a client-side Array object named FavoriteNumbers, you'd use the following server-side code:
RegisterArrayDeclaration("FavoriteNumbers", "1")
RegisterArrayDeclaration("FavoriteNumbers", "2")
RegisterArrayDeclaration("FavoriteNumbers", "3")

This code would emit the following client-side script:

Notice that each array value passed in must be a string; however, the client-side script rendered sets the values of the Array object as the contents of the string. That is, if you wanted to create an Array with the string values "Scott" and "Jisun", you'd use:
RegisterArrayDeclaration("FavoriteFolks", "'Scott'")
RegisterArrayDeclaration("FavoriteFolks ", "'Jisun'")

Notice that the second input parameters are strings that contain 'Scott' and 'Jisun'—text delimited by a single apostrophe. This would render the following client-side script:
var FavoriteFolks = new Array('Scott', 'Jisun');

RegisterHiddenField(hiddenFieldName,hiddenFieldValue)

In classic ASP there was often the need to pass around various bits of information from one page to another. A common way of accomplishing this was using hidden form fields. (A hidden form field is a form field that is not displayed, but whose value is sent on the form's submission. The syntax for creating a hidden form field is .) The need for passing information around by custom hidden form fields in ASP.NET is greatly reduced since the state of the controls in the page is automatically persisted. If, however, you find that you need to create a custom hidden form field, you can do so through the RegisterHiddenField method.
The RegisterHiddenField method accepts two input parameters: the name of the hidden field and the value. For example, to create a hidden form field with the name foo and the value bar, use the following code:
RegisterHiddenField("foo", "bar")

This would add a hidden form field within the page's form element, like so:

Friday, July 17, 2009

Features in C# 3.0

Implicitly Typed Local Variables
C# 3.0 introduces a new keyword called "var". This new keyword enables you to declare a variable whose type is implicitly inferred from the expression used to initialize the variable. For example, consider the following line of code:
var i = 30;

The preceding line initializes the variable i to value 30 and gives it the type of integer. Note that "i" is strongly typed to an integer—it is not an object or a VB6 variant, nor does it carry the overhead of an object or a variant.
We can also write for strings like…
var s = "Hello again!";


In addition to implicitly declaring variables, you can also use the var keyword for declaring arrays as well. For example, consider the following lines of code:
int[] numbers = new int[] { 1, 2, 3, 4, 5};
string[] names = new string[] { "Dave", "Doug", "Jim" };

By using the var keyword, you can rewrite the preceding lines of code as follows:
var numbers = new[] { 1, 2, 3, 4, 5};
var names = new[] { "Dave", Doug, "Jim" };

The var keyword is NOT a completely new type, instead the compiler just takes a look at the right-hand side of the expression. If the right-hand side is an int, for example, the compiler will "replace" the var keyword with int.

Object initializers
Whenever you declare a class, most of the times the class is used only as a placeholder with getters and setters for holding property values without any additional logic. For example, consider a simple class like the following:
public class Person
{
int _id;
string _firstName;
string _lastName;

public int ID
{
get{return _id;}
set{_id = value;}
}
public string FirstName
{
get{return _firstName;}
set{_firstName = value;}
}
public string LastName
{
get{return _lastName;}
set{_lastName = value;}
}
public string FullName
{
get{return FirstName + " " + LastName;}
}
}


As you can see from the above class declaration, it doesn't contain any additional logic. The get and set properties are repetitive and they simply set or get the values of the properties without adding any value. In C#, you can simplify that by leveraging the new feature named Auto-Implemented properties. By taking advantage of this new feature, you can rewrite the above code as follows:
public class Person
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName
{
get
{
return FirstName + " " + LastName;
}
private set {;}
}
}

In the above code, when you declare a property, the compiler automatically creates a private, anonymous field that is available only to the property's get and set accessors. Note that the auto implemented properties must declare both a get and set accessor. However if you need to create a read-only property, modify the scope of the set accessor to be private.

Object and Collection Initializers
In previous versions of C#, you would create the object in one step and then populate its properties in a separate next step. However with C# 3.0, you can create the object as well as set its properties in a single line of code. For example, consider the following lines of code:
Person obj = new Person();
obj.ID = 1;
obj.FirstName = "Thiru";
obj.LastName = "Thangarathinam";
MessageBox.Show(obj.FullName);

In the above code, you create the Person object and set its properties appropriate values. By leveraging the object initializers feature, you can simplify the above code as follows:
Person obj = new Person { ID = 1, FirstName = "Thiru", LastName = "Thangarathinam" };
MessageBox.Show(obj.FullName);

In the above code lines of code, you directly assign the values to the properties of the Person object. Although you can simulate this behavior using constructor for the object, object initializers reduce the need to have a specific constructor for every variation of argument variation we need over time.
In C# 2.0, when you want to populate a collection, you need to write the following line of code:
List names = new List();
names.Add("David");
names.Add("Tim");
names.Add("Doug");

Now with the introduction of the new collection initializers feature in C# 3.0, you can shorten the above lines of code to a single line of code:
List names = new List {"David", "Tim", "Doug"};


Extension methods
Another cool thing is that you're able to add (static) methods to existing (default) classes. As an example, here is the code to add a ToMD5() method to the string class:

public static class StringExtensions
{
public static string ToMD5(this string s)
{
System.Security.Cryptography.MD5 md5;
md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] result = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(s));
// Return the result, replace unneeded "-"
return System.BitConverter.ToString(result).Replace("-", string.Empty);
}
}



Once compiled, all string objects now have the ToMD5 method. If you placed the extension class above in a seperate namespace, you should import this namespace to enable the usage. Example below:
string s = "Hello, this string is gonna be MD5-ed!";
Console.WriteLine(s.ToMD5()); // Prints the MD5 hash


As you can see from the preceding lines of code, the extension methods allow you to write cleaner and easy-to-maintain code.
Here are some of the key characteristics of extension methods:
• The extension method as well as the class that contains the extension method should be static.
• Although extension methods are static methods, they are invoked as if they are instance methods.
• The first parameter passed to the extension method specifies the type on which they operate and it is preceded by the "this" keyword.
• From within the extension method, you can't access the private variables of the type you are extending.
• Instance methods take precedence over extension methods in situations where they have same signature.


Anonymous Types
As the name suggests, anonymous types allow you to create a type on-the-fly at compile time. The newly created type has public properties and backing fields defined for the members you initialize during construction. For example, consider the following line of code:
var obj=new{ID=1,FirstName="Thiru",LastName="Thangarathinam"};

In the above line, you just specify the various attributes you want to have in the anonymous class and assign the instantiated object to a variable of type "var". The actual type assigned to obj is determined by the compiler. Since the compiler assigns the name of the type only at compile time, you can't pass an anonymous type to another method and it can only be used within the method they were declared.
When the compiler sees the above code, it automatically declares a class as follows:
class __Anonymous1
{
private int _id = 1;
private string _firstName = "Thiru";
private string _lastName = "Thangarathinam";

public int ID
{
get{return _id;}
set{_id = value;}
}
public string FirstName
{
get{return _firstName;}
set{_firstName = value;}
}
public string LastName
{
get{return _lastName;}
set{_lastName = value;}
}
}

Anonymous Types use the Object Initializer to specify what properties the new type will be declare.
Note that the anonymous types are just meant to be placeholders for quickly defining entity types and you can't add methods or customize the behavior of an anonymous type.

Lambda Expressions
Lambda expressions are simply functions and they are declared in the context of expressions than as a member of a class. It is an inline expression or a statement block which can be used to pass arguments to a method or assign value to delegate. All lambda expressions use the lambda operator => and the left side of the operator denotes the results and the right side contains the expression to be evaluated. For instance, consider the following lambda expression:
age => age + 1

The above function takes one argument named age, and returns age + 1 as the result. As you can see, Lambda expressions follow the below syntax:
(parameter-list) => expression;

where expression can be any C# expression or a block of code. Just like anonymous methods you can use a lambda expression in place of a delegate. Here are some sample lambda expressions and their corresponding delegates.
//Explicitly typed parameter
(Person obj) => MessageBox.Show(obj.FirstName.ToUpper());

//Implicitly typed parameter
(obj) => obj.FirstName == "Thiru";

//Explicitly typed parameter
(int a, int b) => a + b

//Implicitly typed parameter
(x, y) => { return x + y; }


As you see from the preceding lines of code, lambda expressions can be written in such a way that it can infer the parameter type from the signature of the delegate it is assigned to.

Query Expressions
This feature, also known as LINQ (Language Integrated Query), allows you to write SQL-like syntax in C#.
For instance, you may have a class that describes your data as follows:
public class CoOrdinate
{
public int x ;
public int y;
}

You now could easily declare the logical equivalent of a database table inside C# as follows:
// Use Object and collection initializers
List coords = ... ;

And now that you have your data as a collection that implements IEnumerable, you easily can query this data as follows:
var filteredCoords =
from c in coords
where x == 1
select (c.x, c.y)

In the SQL-like syntax above, "from", "where", and "select" are query expressions that take advantage of C# 3.0 features such as anonymous types, extension methods, implicit typed local variables, and so forth. This way, you can leverage SQL-like syntax and work with disconnected data easily.
Each query expression is actually translated into a C#-like invocation behind the scenes. For instance, the following:
where x == 1
Translates to this:
coords.where(c => c.x == 1)

As you can see, the above looks an awful lot like a lambda expression and extension method. C# 3.0 has many other query expressions and rules that surround them.

Friday, July 3, 2009

JSON (JavaScript Object Notation)

JSON is a part of the ECMAScript standard since ECMA has defined in 1999 the eval() function that parses the format.
It has been popularized with the success of Ajax.
The JSON word appears often when one is speaking about Ajax. We know this is another data format, that can replace XML, and this format is supported by a lot of programmers. But what is exactly JSON, what are the advantages?

Why JSON?

The benefit of JSON is that it is recognized natively by JavaScript. No need for parsing an XML document to extract the data and get it throught the net.

JSON and XML

Benefits of JSON:
- The easiness of reading.
- The easiness of using.


Benefits of XML:
- XML is extensible.
- It is widely used and recognized by almost all programming languages.


Unfortunally, both XML and JSON are enable to integrate a large amount of data in binary form.

The syntax of JSON

The components of JSON:
- An object: contains objets or attributes.
- A scalar variable: Number, String, Boolean.
- An array.
- Literal values: null, true, false, "string of characters", and numerical values.
Object


It contains a member or a list of members, and each member has the form:
"name" : "value"

The syntax of the object is:
{ member, member, .... }


Array
A collection of values, separated by commas.
[ value, value, ....]


Values
A value may be: an object, an array, a litteral (string, number, true, false, null).
Nothing more is required to create a JSON file!

Example of JSON file
A simple example, designing a menu:
It is an object made of members that are an attribute and an array that holds other objects, the rows of the menu.

{
"menu": "File",
"commands": [
{
"title": "New",
"action":"CreateDoc"
},
{
"title": "Open",
"action": "OpenDoc"
},
{
"title": "Close",
"action": "CloseDoc"
}
]
}


The XML equivalent:




How to use the format
The JSON file allows to load data from the server or to send data to it, in this format. For example, storing the content of a form, just filled by an user. This involves three steps: the browser processing, the server processing, and the data exchange between them.

Client side (browser)
This is rather easy, as JSON is a part of the JavaScript definition. The content of a file, or the definition of the data is assigned to a variable, and this variable becomes an object of the program.

Server side
JSON file are used by various programming languages, including PHP and Java thanks to parsers that allow to get the content and that may even convert it into classes and attributes of the language.
The json.org includes a C parser and a list of parsers in other languages.

Data exchange
Loading a file may be accomplished from JavaScript in several ways:
- direct including of the file into the HTML page, as a JavaScript .js external file.
- loading by a JavaScript command.
- using XMLHttpRequest.


The JSON file is parsed by the eval() JavaScript function.

Sending the file to the server may be accomplished by XMLHttpRequest. The file is sent as a text file and processed by the parser of the programming language that uses it.
Example
The XMLHttpRequest code:
var req = new XMLHttpRequest();
req.open("GET", "file.json", true);
req.onreadystatechange = myCode; // the handler
req.send(null);

The JavaScript handler:
function myCode()
{
if (req.readyState == 4)
{
var doc = eval('(' + req.responseText + ')');
}
}


Using the data:
var menuName = document.getElementById('jsmenu'); // finding a field
menuName.value = doc.menu.value; // assigning a value to the field


How to access data:
doc.commands[0].title // read value of the "title" field in the array
doc.commands[0].action // read value of the "action" field in the array

XML Vs JSON

Extensible Markup Language (XML) is a text format derived from Standard Generalized Markup Language (SGML). Compared to SGML, XML is simple. HyperText Markup Language (HTML), by comparison, is even simpler. Even so, a good reference book on HTML is an inch thick. This is because the formatting and structuring of documents is a complicated business.

Most of the excitement around XML is around a new role as an interchangeable data serialization format. XML provides two enormous advantages as a data representation language:

1. It is text-based.
2. It is position-independent.


These together encouraged a higher level of application-independence than other data-interchange formats. The fact that XML was already a W3C standard meant that there wasn't much left to fight about (or so it seemed).

Unfortunately, XML is not well suited to data-interchange, much as a wrench is not well-suited to driving nails. It carries a lot of baggage, and it doesn't match the data model of most programming languages. When most programmers saw XML for the first time, they were shocked at how ugly and inefficient it was. It turns out that that first reaction was the correct one. There is another text notation that has all of the advantages of XML, but is much better suited to data-interchange. That notation is JavaScript Object Notation (JSON).

The most informed opinions on XML suggest that XML has big problems as a data-interchange format, but the disadvantages are compensated for by the benefits of interoperability and openness.

JSON promises the same benefits of interoperability and openness, but without the disadvantages.

Let's compare XML and JSON on the attributes that the XML community considers important.

Simplicity
XML is simpler than SGML, but JSON is much simpler than XML. JSON has a much smaller grammar and maps more directly onto the data structures used in modern programming languages.

Extensibility
JSON is not extensible because it does not need to be. JSON is not a document markup language, so it is not necessary to define new tags or attributes to represent data in it.

Interoperability
JSON has the same interoperability potential as XML.

Openness
JSON is at least as open as XML, perhaps more so because it is not in the center of corporate/political standardization struggles.



In summary these are some of the advantages of XML.

XML is human readable

JSON is much easier for human to read than XML. It is easier to write, too. It is also easier for machines to read and write.

XML can be used as an exchange format to enable users to move their data between similar applications
The same is true for JSON.

XML provides a structure to data so that it is richer in information
The same is true for JSON.

XML is easily processed because the structure of the data is simple and standard

JSON is processed more easily because its structure is simpler.

There is a wide range of reusable software available to programmers to handle XML so they don't have to re-invent code
JSON, being a simpler notation, needs much less specialized software. In the languages JavaScript and Python, the JSON notation is built into the programming language; no additional software is needed at all. In other languages, only a small amount of JSON-specific code is necessary. For example, a package of three simple classes that makes JSON available to Java is available for free from JSON.org.

XML separates the presentation of data from the structure of that data.
XML requires translating the structure of the data into a document structure. This mapping can be complicated. JSON structures are based on arrays and records. That is what data is made of. XML structures are based on elements (which can be nested), attributes (which cannot), raw content text, entities, DTDs, and other meta structures.

A common exchange format
JSON is a better data exchange format. XML is a better document exchange format. Use the right tool for the right job.

Many views of the one data
JSON does not provide any display capabilities because it is not a document markup language.

Self-Describing Data
XML and JSON have this in common.

Complete integration of all traditional databases and formats
(Statements about XML are sometimes given to a bit of hyperbole.) XML documents can contain any imaginable data type - from classical data like text and numbers, or multimedia objects such as sounds, to active formats like Java applets or ActiveX components.

JSON does not have a <[CDATA[]]> feature, so it is not well suited to act as a carrier of sounds or images or other large binary payloads. JSON is optimized for data. Besides, delivering executable programs in a data-interchange system could introduce dangerous security problems.

Internationalization
XML and JSON both use Unicode.

Open and extensible
XML’s one-of-a-kind open structure allows you to add other state-of-the-art elements when needed. This means that you can always adapt your system to embrace industry-specific vocabulary.

Those vocabularies can be automatically converted to JSON, making migration from XML to JSON very straightforward.

XML is easily readable by both humans and machines
JSON is easier to read for both humans and machines.

XML is object-oriented
Actually, XML is document-oriented. JSON is data-oriented. JSON can be mapped more easily to object-oriented systems.

XML is being widely adopted by the computer industry
JSON is just beginning to become known. Its simplicity and the ease of converting XML to JSON makes JSON ultimately more adoptable.

Tuesday, June 30, 2009

Bubbling an Event

The ASP.NET page framework provides a technique called event bubbling that allows a child control to propagate events up its containment hierarchy. Event bubbling enables events to be raised from a more convenient location in the controls hierarchy and allows event handlers to be attached to the original control as well as to the control that exposes the bubbled event.

Event bubbling is used by the data-bound controls (Repeater, DataList, and DataGrid) to expose command events raised by child controls (within item templates) as top-level events. While ASP.NET server controls in the .NET Framework use event bubbling for command events (events whose event data class derives from CommandEventArgs), any event defined on a server control can be bubbled.

A control can participate in event bubbling through two methods that it inherits from the base class System.Web.UI.Control. These methods are OnBubbleEvent and RaiseBubbleEvent. The following code shows the signatures of these methods.

[C#]
protected virtual bool OnBubbleEvent
(
object source,
EventArgs args
);
protected void RaiseBubbleEvent(
object source,
EventArgs args
);
[Visual Basic]
Overridable Protected Function OnBubbleEvent( _
ByVal source As Object, _
ByVal args As EventArgs _
) As Boolean
Protected Sub RaiseBubbleEvent( _
ByVal source As Object, _
ByVal args As EventArgs _
)

The implementation of RaiseBubbleEvent is provided by Control and cannot be overridden. RaiseBubbleEvent sends the event data up the hierarchy to the control's parent. To handle or to raise the bubbled event, a control must override the OnBubbleEvent method.

A control that has an event bubbled to it does one of the following three things.

  • It does nothing, in which case the event is automatically bubbled up to its parent.
  • It does some processing and continues to bubble the event. To accomplish this, a control must override OnBubbleEvent and invoke RaiseBubbleEvent from OnBubbleEvent. The following code fragment bubbles an event after checking for the type of the event arguments.
    [C#]
    protected override bool OnBubbleEvent(object source, EventArgs e) {           if (e is CommandEventArgs) {
    // Adds information about an Item to the
    // CommandEvent.
    TemplatedListCommandEventArgs args =
    new TemplatedListCommandEventArgs(this, source, (CommandEventArgs)e);
    RaiseBubbleEvent(
    this, args);
    return true;
    }
    return false;
    }
    [Visual Basic]
    Protected Overrides Function OnBubbleEvent(source As Object, e As EventArgs) As Boolean
    If TypeOf e Is CommandEventArgs Then
    ' Adds information about an Item to the
    ' CommandEvent.
    Dim args As New TemplatedListCommandEventArgs(Me, source, CType(e, CommandEventArgs))
    RaiseBubbleEvent(Me, args)
    Return True
    End If
    Return False
    End Function

  • It stops bubbling the event and raises and/or handles the event. Raising an event involves invoking the method that dispatches the event to listeners. To raise the bubbled event, a control must override OnBubbleEvent to invoke the OnEventName method that raises the bubbled event. A control that raises a bubbled event generally exposes the bubbled event as a top-level event. The following code fragment raises a bubbled event.
    [C#]
    protected override bool OnBubbleEvent(object source, EventArgs e) {
    bool handled = false;

    if (e is TemplatedListCommandEventArgs) {
    TemplatedListCommandEventArgs ce = (TemplatedListCommandEventArgs)e;

    OnItemCommand(ce);
    handled =
    true;
    }
    return handled;
    }
    [Visual Basic]
    Protected Overrides Function OnBubbleEvent(source As Object, e As EventArgs) As Boolean
    Dim handled As Boolean = False

    If TypeOf e Is TemplatedListCommandEventArgs Then
    Dim ce As TemplatedListCommandEventArgs = CType(e, TemplatedListCommandEventArgs)

    OnItemCommand(ce)
    handled = True
    End If
    Return handled
    End Function

For samples that demonstrate event bubbling, see Event Bubbling Control Sample and Templated Data-Bound Control Sample.

Note While the method that enables event bubbling, OnBubbleEvent, follows the standard .NET Framework naming pattern for methods that raise events, there is no event named BubbleEvent. The bubbled event is exposed as a top-level event in the control that stops event bubbling. For example, the DataList control exposes Command events from controls in its template as ItemCommand events. Note also that the standard signature of OnEventName methods in the .NET Framework has one argument (protected void OnEventName (EventArgs e)). However, OnBubbleEvent has two arguments because the event originates outside the control; the second argument supplies the source.

The discussion so far shows how a control can respond to an event that is bubbled up to it. The following section shows how to author a control that defines a bubbled event.

Defining a Bubbled Event

If you want your control to enable event bubbling for an event that it defines, it must invoke the RaiseBubbleEvent from the OnEventName method that raises the event. No additional work needs to be done from within the control. The following code fragment shows a control that defines a Command event that enables bubbling.

[C#]
protected virtual void OnCommand(CommandEventArgs e) {
CommandEventHandler handler = (CommandEventHandler)Events[EventCommand];
if (handler != null)
handler(
this,e);

// The Command event is bubbled up the control hierarchy.
RaiseBubbleEvent(
this, e);
}
[Visual Basic]
Protected Overridable Sub OnCommand(e As CommandEventArgs)
Dim handler As CommandEventHandler = CType(Events(EventCommand), CommandEventHandler)
If Not (handler Is Nothing) Then
handler(Me, e)
End If
' The Command event is bubbled up the control hierarchy.
RaiseBubbleEvent(Me, e)
End Sub

Note Event bubbling is not limited to command events. You can use the mechanism described here to bubble any event.

Event Bubbling

Event Bubbling



Suppose you have a element inside an element

-----------------------------------
| element1 |
| ------------------------- |
| |element2 | |
| ------------------------- |
| |
-----------------------------------


and both have an onClick event handler. If the user clicks on element2 he causes a click event in both element1 and element2. But which event fires first? Which event handler should be executed first? What, in other words, is the event order?
Two models

Not surprisingly, back in the bad old days Netscape and Microsoft came to different conclusions.


  • Netscape said that the event on element1 takes place first. This is called event capturing.
  • Microsoft maintained that the event on element2 takes precedence. This is called event bubbling.


The two event orders are radically opposed. Explorer only supports event bubbling. Mozilla, Opera 7 and Konqueror support both. Older Opera's and iCab support neither.

Event capturing

When you use event capturing

               | |
---------------| |-----------------
| element1 | | |
| -----------| |----------- |
| |element2 \ / | |
| ------------------------- |
| Event CAPTURING |
-----------------------------------



the event handler of element1 fires first, the event handler of element2 fires last.
Event bubbling

When you use event bubbling

               / \
---------------| |-----------------
| element1 | | |
| -----------| |----------- |
| |element2 | | | |
| ------------------------- |
| Event BUBBLING |
-----------------------------------



the event handler of element2 fires first, the event handler of element1 fires last.

W3C model

W3C has very sensibly decided to take a middle position in this struggle. Any event taking place in the W3C event model is first captured until it reaches the target element and then bubbles up again.

                 | |  / \
-----------------| |--| |-----------------
| element1 | | | | |
| -------------| |--| |----------- |
| |element2 \ / | | | |
| -------------------------------- |
| W3C event model |
------------------------------------------



You, the web developer, can choose whether to register an event handler in the capturing or in the bubbling phase. This is done through the addEventListener() method explained on the Advanced models page. If its last argument is true the event handler is set for the capturing phase, if it is false the event handler is set for the bubbling phase.

Suppose you do

element1.addEventListener('click',doSomething2,true)
element2.addEventListener('click',doSomething,false)


If the user clicks on element2 the following happens:

1. The click event starts in the capturing phase. The event looks if any ancestor element of element2 has a onclick event handler for the capturing phase.
2. The event finds one on element1. doSomething2() is executed.
3. The event travels down to the target itself, no more event handlers for the capturing phase are found. The event moves to its bubbling phase and executes doSomething(), which is registered to element2 for the bubbling phase.
4. The event travels upwards again and checks if any ancestor element of the target has an event handler for the bubbling phase. This is not the case, so nothing happens.



The reverse would be


element1.addEventListener('click',doSomething2,false)
element2.addEventListener('click',doSomething,false)


Now if the user clicks on element2 the following happens:

1. The click event starts in the capturing phase. The event looks if any ancestor element of element2 has a onclick event handler for the capturing phase and doesn’t find any.
2. The event travels down to the target itself. The event moves to its bubbling phase and executes doSomething(), which is registered to element2 for the bubbling phase.
3. The event travels upwards again and checks if any ancestor element of the target has an event handler for the bubbling phase.
4. The event finds one on element1. Now doSomething2() is executed.


Use of event bubbling

Few web developers consciously use event capturing or bubbling. In Web pages as they are made today, it is simply not necessary to let a bubbling event be handled by several different event handlers. Users might get confused by several things happening after one mouse click, and usually you want to keep your event handling scripts separated. When the user clicks on an element, something happens, when he clicks on another element, something else happens.

Of course this might change in the future, and it’s good to have models available that are forward compatible. But the main practical use of event capturing and bubbling today is the registration of default functions.

It always happens

What you first need to understand is that event capturing or bubbling always happens. If you define a general onclick event handler for your entire document

document.onclick = doSomething;
if (document.captureEvents) document.captureEvents(Event.CLICK);

any click event on any element in the document will eventually bubble up to the document and thus fire this general event handler. Only when a previous event handling script explicitly orders the event to stop bubbling, it will not propagate to the document.

Uses

Because any event ends up on the document, default event handlers become possible. Suppose you have this page:

------------------------------------
| document |
| --------------- ------------ |
| | element1 | | element2 | |
| --------------- ------------ |
| |
------------------------------------


element1.onclick = doSomething;
element2.onclick = doSomething;
document.onclick = defaultFunction;

Now if the user clicks on element1 or 2, doSomething() is executed. You can stop the event propagation here, if you wish. If you don’t the event bubbles up to defaultFunction(). If the user clicks anywhere else defaultFunction() is also executed. This might be useful sometimes.

Setting document–wide event handlers is necessary in drag–and–drop scripts. Typically a mousedown event on a layer selects this layer and makes it respond to the mousemove event. Though the mousedown is usually registered on the layer to avoid browser bugs, both other event handlers must be document–wide.

Remember the First Law of Browserology: anything can happen, and it usually does when you’re least prepared for it. So it may happen that the user moves his mouse very wildly and the script doesn’t keep up so that the mouse is not over the layer any more.

  • If the onmousemove event handler is registered to the layer, the layer doesn’t react to the mouse movement any more, causing confusion.
  • If the onmouseup event handler is registered on the layer, this event isn’t caught either so that the layer keeps reacting to the mouse movements even after the user thinks he dropped the layer. This causes even more confusion

.

So in this case event bubbling is very useful because registering your event handlers on document level makes sure they’re always executed.

Turning it off


But usually you want to turn all capturing and bubbling off to keep functions from interfering with each other. Besides, if your document structure is very complex (lots of nested tables and such) you may save system resources by turning off bubbling. The browser has to go through every single ancestor element of the event target to see if it has an event handler. Even if none are found, the search still takes time.

In the Microsoft model you must set the event’s cancelBubble property to true.

window.event.cancelBubble = true

In the W3C model you must call the event’s stopPropagation() method.

e.stopPropagation()

This stops all propagation of the event in the bubbling phase. Stopping event propagation in the capturing phase is impossible. One wonders why.

For a complete cross-browser experience do

function doSomething(e)
{
if (!e) var e = window.event;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
}

Setting the cancelBubble property in browsers that don’t support it doesn’t hurt. The browser shrugs and creates the property. Of course it doesn’t actually cancel the bubbling, but the assignment itself is safe.

currentTarget

As we’ve seen earlier, an event has a target or srcElement that contains a reference to the element the event happened on. In our example this is element2, since the user clicked on it.

It is very important to understand that during the capturing and bubbling phases (if any) this target does not change: it always remains a reference to element2.

But suppose we register these event handlers:

element1.onclick = doSomething;
element2.onclick = doSomething;

If the user clicks on element2 doSomething() is executed twice. But how do you know which HTML element is currently handling the event? target/srcElement don’t give a clue, they always refer to element2 since it is the original source of the event.

To solve this problem W3C has added the currentTarget property. It contains a reference to the HTML element the event is currently being handled by: exactly what we need. Unfortunately the Microsoft model doesn’t contain a similar property.

You can also use the this keyword. In the example above it refers to the HTML element the event is handled on, just like currentTarget.

Problems of the Microsoft model

But when you use the Microsoft event registration model the this keyword doesn’t refer to the HTML element. Combined with the lack of a currentTarget–like property in the Microsoft model, this means that if you do

element1.attachEvent('onclick',doSomething)
element2.attachEvent('onclick',doSomething)

you cannot know which HTML element currently handles the event. This is the most serious problem with the Microsoft event registration model.