Introduction:
In this article, I will explain how to extend the
DataGrid class to provide some new
functionalities. Building new web controls from scratch
is not the best solution in most of cases, just adding some new functionalities
to existing .NET Web controls will save you time and provide more stability. In
addition, they'll be more compatible with any new versions of .NET framework.
Functionalities:
- Add the total number of rows in the
DataGrid footer.
- Add Serial column
Source Code:
Let's explain the code now step by step, first we have to create the class that
will extend the DataGrid class:
using System;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
System.ComponentModel;
using
System.Collections ;
using
System.Data;
[assembly:TagPrefix("BNaffa.Web.Ui.WebControls","ExtendedDG")]
namespace
BNaffa.Web.UI.WebControls
{
[
DefaultProperty("ShowNoRows"),
ToolboxData("<{0}:ExtendedDG
runat=server></{0}:ExtendedDG>")
]
public
class ExtendedDG :
DataGrid
{
// strings constants represent the view state indexes
const
string SHOW_NO_ROWS="ShowNoRows";
const
string NO_ROWS="NoOfRows";
const
string SHOW_SERIAL ="ShowSerial";
// Constructor
public
ExtendedDG():base()
{
}
// Properties & Methods go here
}
Then, we'll add the following two properties:
-
ShowNoRows [true/false]
-
ShowSerial
[true/false]
[Bindable(true),
Category("Appearance")
]
public
bool
ShowNoRows
{
get
{
return
Convert.ToBoolean(ViewState[SHOW_NO_ROWS]);
}
set
{
ViewState[SHOW_NO_ROWS]=
value;
}
}
[Bindable(true),
Category("Appearance")
]
public
bool
ShowSerial
{
get
{
return
Convert.ToBoolean(ViewState[SHOW_SERIAL]);
}
set
{
ViewState[SHOW_SERIAL]=
value;
}
}
This
private function will check if we are in the design
mode or in runtime mode:
private
bool
IsInDesignMode()
{
if (this.Site
!= null)
return
this.Site.DesignMode;
return
false;
}
Total Number Of
Rows Functionality:
Now we want to know the number of rows for current
DataSource. Ok, how do we get that? One of solutions
is to cast the data source property for the data grid to a data set or data table
and get the number of rows. But I don't prefer this way!! I will give you a short
way without casting cost.
We will override the method
CreateColumnSet which be called when you invoke
the method DataBind:
protected
override ArrayList
CreateColumnSet
(PagedDataSource
dataSource,
bool useDataSource)
{
if
(dataSource != null)
ViewState[NO_ROWS]
= dataSource.DataSourceCount;
return
base.CreateColumnSet
(dataSource, useDataSource);
}
As you see, this function will receive an object
of type PagedDataSource,
this object contains a DataSourceCount property,
Then we will save this number in the
ViewState collection. Using this method, you can get
the data source count without casting and with any type
of data sources [DataSet, DataView,
DataTable, ArrayList, etc...]
Now we will override the method
OnItemCreated, to add the total number of rows
in the DataGrid footer:
protected
override void
OnItemCreated(DataGridItemEventArgs
e)
{
base.OnItemCreated
(e);
if (!IsInDesignMode())
// Only in Runtime Mode
{
if (e.Item.ItemType
== ListItemType.Footer)
{
if(ShowNoRows
&& ShowFooter )
{
if(e.Item.Cells.Count
> 0)
{
e.Item.Cells[0].Text
= ViewState[NO_ROWS] + " Rows.";
}
}
}
}
}
Serial Column Functionality:
Before writing the serial number to the
DataGrid, we have to add a template column for the serial
field, so we must have this class which implements the interface
ITemplate and the method
InstantiateIn:
public
class MyColumn:ITemplate
{
public
void InstantiateIn
( Control container )
{
}
}
We will add this serial column in the
OnOnit Method which handles the
DataGrid initiation process:
protected
override void
OnInit(EventArgs e)
{
base.OnInit (e);
if (!
IsInDesignMode())
// Only in Runtime Mode
{
TemplateColumn tmpCol
= new
TemplateColumn();
MyColumn myCol
= new
MyColumn();
tmpCol.ItemTemplate = myCol;
this.Columns.Add(tmpCol);
}
}
Now we have to add the serials to the new Column,
we will add another fragment code to the previous overridden method
OnItemCreated, so it will be like this:
protected
override void
OnItemCreated(DataGridItemEventArgs
e)
{
base.OnItemCreated
(e);
if (!IsInDesignMode())
// Only in Runtime Mode
{
if (e.Item.ItemType
== ListItemType.Footer)
{
if(ShowNoRows
&& ShowFooter )
{
if(e.Item.Cells.Count
> 0)
{
e.Item.Cells[0].Text
= ViewState[NO_ROWS] + " Rows.";
}
}
}
if (e.Item.ItemType
== ListItemType.Header)
{
if(ShowSerial
&& ShowHeader )
{
e.Item.Cells[0].Text
= "#";
}
}
else
if (e.Item.ItemType
== ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem
)
{
if(ShowSerial)
{
e.Item.Cells[0].Text=
(e.Item.ItemIndex +
(this.PageSize*this.CurrentPageIndex
) + 1 ).ToString();
}
}
}
}
The important thing here is the equation that
calculates the current row number, we will consider
the current page index to work properly with DataGrid
paging (e.Item.ItemIndex
+ (this.PageSize *
this.CurrentPageIndex )
+ 1 )
Now you can compile the project and use the
assembly to add new control to your toolbox tab in Visual Studio.NET., and you can
use the new DatarGrid and set these properties
ShowNoSerial, ShowSerial
to true to show this functionality.


Download
Source Code and Sample!
About Author:
Bashar
Naffa’, MCSD/MCAD.
I have worked in .NET since Beta, and now digging
deep inside .NET Framework 2.0!