Creating a Row-Selectable DataGrid Control
By Scott Mitchell
Introduction
One of the main benefits of ASP.NET is the ease with which its functionality can be extended. Since all of the ASP.NET Web controls are, in actuality, classes in the .NET Framework, any developer can extend the functionality of a built-in Web control by creating a new class that derives from the Web control. This topic has been discussed previously on 4Guys in an article titled Easily Adding Functionality to ASP.NET Server Controls. In this earlier article we saw how to extend the Calendar Web control so that when the mouse moved over a particular day in the month, the day became highlighted. (See the live Calendar demo for more information.)
Sometime ago I created a custom Web control that extended the DataGrid, adding similar highlighting functionality on a row-by-row basis. That is, when the user moves his mouse over a DataGrid row, the entire row becomes highlighted. Furthermore, the control allows for the row to be "clickable." That is, a user can move his mouse anywhere over a row and click their mouse button. This will cause a postback and will trigger a specified DataGrid event.
In this article we'll take a look at the code for this custom control. We'll also discuss how to start using this control on your ASP.NET Web pages. If you've ever wanted a DataGrid that was selectable by row and offered row-level highlighting, read on! (Also, be sure to give the live demo a whirl!)
Examining the Client-Side Source Code
The DataGrid Web control renders as an HTML
<table>
, with each row of the DataGrid as a
<tr>
tag and each column a <td>
. HTML elements can trigger client-side JavaScript
code to execute when a mouse moves over the element via the onmouseover
and onmouseout
client-side events. For example, you could have a messagebox displayed whenever someone moved their mouse over
a paragraph by using the following mix of HTML and script:
<p onmouseover="alert('Hello, World!');">
|
To have a table row become highlighted when the mouse moves over it we will need to have the DataGrid control emit HTML and script so that the rendered content looks something like:
|
The call to the client-side function prettyDG_changeBackColor
sets the background color of the passed-in
<tr>
to pink if the highlight
parameter is true, and sets it back to its previously
saved color if highlight
is false. A thorough discussion of this client-side code is beyond the scope
of this article; to learn more about dynamic HTML, refer to the DHTML
Tutorials at W3 Schools.
Implementing a Row-Highlighting DataGrid Class
Now that we know the markup the DataGrid must emit in order to provide row-level highlighting, the next challenge is to implement this functionality in a custom server control. If you were building this control from scratch you'd start by creating a new Visual Studio .NET Project of type Web Control Library. (The screenshot to the right shows the New Project dialog box in Visual Studio .NET 2003.) However, the complete source code and VS.NET 2003 Project files are downloadable at the end of this article.
To create a custom control with the desired features, we can create a class that inherits the DataGrid
class.
This means that our new class will automatically have all of the public and protected properties, methods, and events
of the DataGrid, without us having to write one line of code! We can simply focus on adding the extended functionality.
To provide row-highlighting functionality for the DataGrid we'll need two properties in our class:
RowHighlightColor
- specifies the color to highlight the row.RowSelectionEnabled
- a Boolean value indicating whether or not row highlighting should be used.
|
One thing to notice is that the property values are being stored and retrieved from the ViewState
state bag. By saving these properties to the ViewState
, any programmatic changes to these
properties are persisted across postback. A thorough discussion of why this code is needed, or how view state works
underneath the covers, is a bit off-topic for this article. For more information refer to
Understanding
ASP.NET View State.
We now need to inject the necessary client-side script. There are two bits of client-side code that need to be
added to the DataGrid - the onmouseover
/ onmouseout
event handlers in the <tr>
tags, and the <script>
block with the prettyDG_changeBackColor
function.
To emit the
onmouseover
/ onmouseout
event handlers we need to override the DataGrid's CreateItem()
method. CreateItem()
is called once for every record in the DataSource
being bound to the DataGrid.
CreateItem()
creates a new DataGridItem
class (which is what is eventually rendered
as a <tr>
) and returns it. What we need to do is add the onmouseover
/ onmouseout
event handlers, which can be accomplished by using the Attributes
collection of the
DataGridItem
class like so:
|
This overridden CreateItem()
method starts by creating a new DataGridItem
instance.
It then adds the client-side onmouseover
/ onmouseout
event handlers to the
DataGridItem
if the DataGridItem
is not a Header, Footer, or Pager, and if the
RowSelectionEnabled
property is true.
The DataGrid must also emit the client-side <script>
block that contains the
prettyDG_changeBackColor
function. Typically <script>
blocks are emitted in
control's OnPreRender()
method. (For a more in-depth look at this process be sure to read:
Injecting
Client-Side Script from an ASP.NET Server Control.) The following code shows the extended DataGrid's
OnPreRender()
method.
|
Adding Row-Level Clicking
At this point, the extended DataGrid provides capabilities for a page developer to specify a color for the row-level highlighting, and have the rendered DataGrid emit the right mix of HTML and client-side script to have a row become "highlighted" when the user's mouse rests over the row. An additional feature that would be nice to add would be row-level clicking. With row-level clicking, if a user clicks anywhere in a row over which the mouse hovers, a postback occurs and a specified DataGrid event fires on the server-side. This can be particularly useful in parent/child scenarios, when clicking on a row should display detail records about the clicked row, or whisk the user to a URL that has more information on that particular row.
For maximum flexibility, the page developer should be able to specify what DataGrid event fires when a row is clicked.
To account for this, let's add a RowClickEventCommandName
property to the extended DataGrid. When a row
is clicked, a postback will ensue and an event will be bubbled up to the DataGrid based on the value of this
RowClickEventCommandName
property. For example, if you want the DataGrid's DeleteCommand
event to fire whenever a row is clicked, simply set the RowClickEventCommandName
property to "Delete".
If you want the EditCommand
event to fire, set RowClickEventCommandName
to "Edit".
To implement row-level clicking we need to create a custom DataGridItem
class, one that knows what event
to raise when it was clicked. This extended DataGridItem
class, which I call PrettyDataGridItem
,
inherits the DataGridItem
class and only adds one method: RaisePostBackEvent()
.
RaisePostBackEvent()
is the method that the ASP.NET Page
class will automatically call when it
detects that the postback transpired due to the row being clicked. In this method we simply want to bubble the event
up to the DataGrid, which will then raise its ItemCommand
event. An additional DataGrid event
might be raised as well (DeleteCommand
, EditCommand
, etc.), based on the
value of the RowClickEventCommandName
property.
|
Finally, we need to inject some client-side script code that causes a postback when the <tr>
is
clicked. This can be accomplished by adding a client-side onclick
event handler for the
PrettyDataGridItem
. This is accomplished by a call to the CreateClickEvent()
method
from the OnPreRender()
method. The CreateClickEvent()
method simply iterates through
the set of PrettyDataGridItem
s and for each PrettyDataGridItem
that's not a Header, Footer,
or Pager, it adds the onclick
attribute.
|
And that's all there is to it!
Using PrettyDataGrid in an ASP.NET Web Page
At the end of this article you'll find the complete source code for the PrettyDataGrid control. To use it in your ASP.NET Web pages, you can do one of two things:
- You can simply add the assembly in the download (the
.dll
file) to the Toolbox in Visual Studio .NET. To accomplish this, right-click on the Toolbox and choose to Add/Remove Items, and then Browse to the appropriate file. From there, you can drag-and-drop the PrettyDataGrid onto a Web page, set its properties, and off you go! (Be sure to use the right version of the assembly.) - If you want to investigate the code in further detail, you can compile the code yourself. If you are using Visual Studio .NET you can simply open the Project file in the download. (Be sure to open the right version for your version of Visual Studio .NET.) Following that, you'll want to Build the Solution, which will compile the project and create the assembly.
Happy Programming!
Attachments