Building a Full-Featured Custom DataGrid Control

Our Page Setup

Once you peer into our main .NET page, you'll immediately appreciate the awesome power of .NET's code behind technology by noticing that there's no visible client-side code! All you're seeing is a few standard server side controls and our main custom Datagrid control tag. All of the main code responsible for our application is hidden away in our code-behind code, implemented through our @Page and @Register directives.

Remember the old days of ASP? How many lines of code would your page be typically filled with if doing the same thing? Lots and lots, right? All jumbled together and messy. However in .NET, we instead have a total of 25 lines of code (which includes line breaks and stuff)! Now that's the amazing thing about .NET!

Now when our example is ran, it'll utilize JavaScript to do all sort of things, like focus the cursor in our main search box right on Page_Load. We also have some JavaScript attached to our search button, our reset button that clears our search criteria and our results, and finally a function that will always reset focus back to our main textbox after each search.

This type of JavaScript of course may seem cut and dry; well not quite. As we'll soon discover, that is simply is not quite the case, nor so cut and dry as I'll explain. So before we get into actually creating our control, we'll first examine some issues found with our textbox form field, and its interaction with our custom Datagrid control within .NET.

We all know that the process of submitting text from a textbox to a form is pretty straightforward. We type our text, then either hit return or press the submit button; this is the typical scenario. However, here lies the problem that I was just referring to, and really needs correcting. There is an issue with .NET's Textbox server control, that if the user decides to press the enter key from within the textbox containing the same criteria, the form will not postback (as of v1.1 of the .NET Framework, this does not seem to have been resolved)! Physically pressing the submit button is the only way around this. Moreover, the Textbox's OnTextChanged method or the AutoPostBack property can't help us either, unless again you modify the text in some way. The result being we lose our initial Result No. X to X stats; they simply reset to 0. Our previously fired event ceased to reinitialize!

At any rate, not be out done, with a little dash of JavaScript, our issue quickly becomes a non-issue. Bear in mind the code below is formatted to standard JS specifications. After my explanation of the code's function I'll show you how it is implemented in our code-behind scheme.

So, our first step to resolving this is to add an attribute to our Textbox control that'll trigger the JavaScript we need to call, once the user hits return. We do this on Page_Load, like so:

srchTxt.Attributes.Add ("onkeydown", "getButton();");

Here we use our Control's Attribute.Add method that programmatically inserts our JavaScript into the Textbox control's AttributeCollection object. After this has taken place, the above issue if replicated won't occur. The client-side JavaScript (compatible with both IE and Netscape) executes the getButton() function, which simply grabs the users keystrokes, and handles the event. In turn, calling the submitText() function once it detects the Enter Key was pressed, and clicks our form's Submit button for us. Here is the JavaScript:

<script language="JavaScript">

var isIE;
if (navigator.appName == "Microsoft Internet Explorer"){isIE = true;}

function getButton()
{
//Capture Netscape events
if(!isIE) {

document.captureEvents (Event.KEYDOWN);

}

document.onkeydown = submitText

}


function submitText(evt){

var theButtonPressed;

if (isIE){

theButtonPressed = window.event.keyCode;

}else{

theButtonPressed = evt.which;
}

if (theButtonPressed == 13) {

if(isIE){

with(event){

cancelBubble = true;
returnValue = false;

}

}

document.getElementById ("Search").click();

}


}

</script>

Now getting back to our JavaScript code's location, it is all hidden away in our datagrid.aspx.cs code-behind file. Implementing this is done through another magnificent .NET method known as RegisterClientScriptBlock. This method allows us to register client-side script blocks in our page from behind the scenes.

The JavaScript above was discussed in clearer detail simply to show what is being done. Adding this code to our code-behind file is done like so, similar to the bare-bones example listed below:

StringBuilder jsScript = new StringBuilder();
string nl = Environment.NewLine;

jsScript.Append ("<script language=JavaScript>" + nl);

jsScript.Append ("function Hello() { " + nl);
jsScript.Append (" document.write ('Hello'); " + nl);
jsScript.Append ("}" + nl);
jsScript.Append ("</script>" + nl);

RegisterClientScriptBlock("clientScript", jsScript.ToString());

//Close our StringBuilder Object
jsScript = null;

Above we utilized the StringBuilder class to concatenate and format our JavaScript code, and add a nl for our line breaks, using the Environment Class's NewLine member. We then call our RegisterClientScriptBlock method which will add our code after our page's <form runat= server> element, and finally close our StringBuilder object by setting it to null. Once you run the application and view the page's source code, our client-block code will look exactly like the standard JavaScript code we discussed.

Now returning back, one added note regarding the submitText() JavaScript function. IE's event bubbling has to further be disabled, alongside the value returned by our event, so it won't interfere with any other elements higher up on the page, nor allow multiple actions to execute either. Other server controls in our page are there to trigger events that'll interact with our custom Datagrid control. We notice that both the search and reset button's utilize the onClick method for their events, and needless to say, are completely immune to the aforementioned JS behavior. Without complaint, they submit the form and execute the Rebind_Grid method.

<asp:textbox id="srchTxt" runat="server" />
<asp:button text="Search" onClick="Rebind_Grid" runat="server" />
<asp:button text="Reset" onClick="Reset_Grid" runat="server" />

As an added note, our Rebind_Grid Method is also an important method in that it further demonstrates component-property assignment. This method is responsible for sending to our component our SQL query command and binding our datagrid by calling our custom control classes GetDataGrid() method. Finally, in our page we have our Stats Label server control that displays our Datagrid data/count statistics, and again all emanating from our complied control class. How all this occurs is going to be demonstrated later on.

<asp:label id="Stats" runat="server" />

But now that we've covered our initial .aspx page, and any known problems, we can now dig to our control's internal workings and everything pertaining to it.

You might also like...

Comments

About the author

Dimitrios Markatos

Dimitrios Markatos United States

Dimitrios, or Jimmy as his friends call him, is a .NET developer/architect who specializes in Microsoft Technologies for creating high-performance and scalable data-driven enterprise Web and des...

Interested in writing for us? Find out more.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“If Java had true garbage collection, most programs would delete themselves upon execution.” - Robert Sewell