Introduction
While working on the websites Grid-view turns to be very effective, very powerful and rich tool. It helps us to view data in paginated manner. It helps us most of the time developing website, but still there are occasions where we are required to add some features to fulfill the requirement. e.g. Adding check-box column (along with writing JavaScript code), show serial numbers, show page summary, dynamically increase or decrease page size, etc. In this article, I am going to create a custom grid-view control which will help us in this regard.
How the Control is Created
The idea behind this control is very simple:
- Override the
InitializePager
method for customization of gridview
- Create temporary table with Three Cells and give with 100%
- In the fist Cell, Create Navigation Control (Image Buttons for First, Next, Previous, Last,
DropdownList
for showing Page Count)
- Create 4 image buttons with properties
ImageUrl
property so that we can set custom Images for navigation - For Image button, set correct command argument for First, Next, Previous, Last, i.e. (Fist Page has Page index 0, Next page has Current Page Index +1, Previous Button has Current Index +1, Last has Page Count+1)
- Add new eventhandler for the click of
imagebutton
, Dropdownlist
and pass Commandargument
, DropdownValue
as argument to gridview
s pageindex
changing event.
- In the second cell, we show Grid information in labels.
- In the third cell, we create
dropdown
list with custom page size, attach eventhandler
to selected index change and set pagesize
. - Create
Checkbox
columns and Serial Number Columns
- Override
OnRowCreated
method - Check for created row is Header, or
datarow
- Check if
CheckboxColumn
and SerialNoColumn
property is set to true
- If it is
true
then in Header row write Header for Check Box first, and then Serial - If it is
datarow
, then create RowLevelCheckboxes
- Create On
OnLoad
method include JavaScript file from the DLL - On Render, create Top and bottom buttons for Select All and Select None
Using the Code
I will explain most of the code here for Check box Column I have used JavaScript code written by Scott Mitchel. Many thanks to the genius.
Properties for the Custom Gridview Control
Property | Type | Purpose |
CustomPageing | Boolean | Enables/Disables custom paging |
CheckBoxColumn | Boolean | Enables/Disables CheckBox Column |
SerialNo | Boolean | Enables/Disables SR. No. Column |
FirstImage | String | Sets/Gets Images path to First Navigation Button |
NextImage | String | Sets/Gets Images path to Next Navigation Button |
PreviousImage | String | Sets/Gets Images path to Previous Navigation Button |
LastImage | String | Sets/Gets Images path to Last Navigation Button |
Setting Properties
Enables/Disables Custom Paging
public bool CustomPageing
{
get { return _CustomPageing; }
set { _CustomPageing = value; }
}
Enables/Disables CheckBox Column
public bool CheckBoxColumn
{
get
{
return _checkboxColumn;
}
set
{
_checkboxColumn = value;
if (CheckBoxColumn)
{
this.Columns.Insert(0, new BoundField());
}
}
}
Enables/Disables SR. No. Column
public bool SerialNoColumn
{
get
{
return _SrNoColumn;
}
set
{
_SrNoColumn = value;
if (SerialNoColumn)
{
this.Columns.Insert(0, new BoundField());
}
}
}
Sets/Gets Images path to First Navigation Button
public string FirstImage
{
get { return _nav_first; }
set { _nav_first = value; }
}
Other properties for Image Button are the same, so I have avoided repetition.
InitializePager Event
In this Event, we create a table with 3 cells for Page Navigation, Page Summary and Page Size controls attach Event Handlers and add this table into the pager row:
protected override void InitializePager(GridViewRow row,
int columnSpan, PagedDataSource pagedDataSource)
{
if (!CustomPageing)
{
base.InitializePager(row, columnSpan, pagedDataSource);
}
else
{
if (CheckBoxColumn) { columnSpan += 1; }
if (SerialNoColumn) { columnSpan += 1; }
DropDownList ddl = new DropDownList();
ddl.AutoPostBack = true;
for (int i = 0; i < PageCount; i++)
{
ddl.Items.Add(new ListItem(Convert.ToString(i + 1), i.ToString()));
}
ddl.SelectedIndexChanged += new EventHandler(ddl_SelectedIndexChanged);
ddl.SelectedIndex = PageIndex;
DropDownList ddlPageSize = new DropDownList();
ddlPageSize.ID = "PageSize";
ddlPageSize.AutoPostBack = true;
ddlPageSize.Items.Add(new ListItem("- Page Size -", "10"));
ddlPageSize.Items.Add(new ListItem("10", "10"));
ddlPageSize.Items.Add(new ListItem("25", "25"));
ddlPageSize.Items.Add(new ListItem("50", "50"));
ddlPageSize.Items.Add(new ListItem("100", "100"));
ddlPageSize.Items.Add(new ListItem("All",
(this.PageCount * this.PageSize).ToString()));
ddlPageSize.SelectedIndexChanged +=
new EventHandler(ddlPageSize_SelectedIndexChanged);
ImageButton first = new ImageButton();
first.AlternateText = "|<< First ";
first.ImageUrl = (FirstImage == string.Empty) ?
Page.ClientScript.GetWebResourceUrl(typeof(InderGrid),
"Indrajeet.Web.UI.WebControls.First.gif") : FirstImage;
first.CommandArgument = "0";
first.Enabled = PageIndex > 0;
first.Click += new ImageClickEventHandler(navigate_Click);
ImageButton prev = new ImageButton();
prev.AlternateText = " < Prev ";
prev.ImageUrl = (PreviousImage == string.Empty) ?
Page.ClientScript.GetWebResourceUrl(typeof(InderGrid),
"Indrajeet.Web.UI.WebControls.Prev.gif") : PreviousImage;
prev.CommandArgument = string.Format("{0}", (PageIndex - 1));
prev.Enabled = (PageIndex > 0);
prev.Click += new ImageClickEventHandler(navigate_Click);
ImageButton next = new ImageButton();
next.AlternateText = "Next > ";
next.ImageUrl = (NextImage == string.Empty) ?
Page.ClientScript.GetWebResourceUrl(typeof(InderGrid),
"Indrajeet.Web.UI.WebControls.Next.gif") : NextImage;
next.CommandArgument = string.Format("{0}", (PageIndex + 1));
next.Enabled = (PageIndex < (PageCount - 1));
next.Click += new ImageClickEventHandler(navigate_Click);
ImageButton last = new ImageButton();
last.AlternateText = "Last >>|";
last.ImageUrl = (LastImage == string.Empty) ?
Page.ClientScript.GetWebResourceUrl(typeof(InderGrid),
"Indrajeet.Web.UI.WebControls.Last.gif") : LastImage;
last.CommandArgument = string.Format("{0}", (PageCount - 1));
last.Enabled = (PageIndex < (PageCount - 1));
last.Click += new ImageClickEventHandler(navigate_Click);
TableCell CellOne = new TableCell();
CellOne.Controls.Add(first);
CellOne.Controls.Add(prev);
CellOne.Controls.Add(PageOf());
CellOne.Controls.Add(ddl);
CellOne.Controls.Add(PageTotal());
CellOne.Controls.Add(next);
CellOne.Controls.Add(last);
TableCell cellTwo = new TableCell();
cellTwo.Controls.Add(PageInfo(pagedDataSource.DataSourceCount));
TableCell cellThree = new TableCell();
cellThree.Controls.Add(ddlPageSize);
Table PagerTable = new Table();
PagerTable.BorderWidth = 0;
PagerTable.Width = Unit.Percentage(100);
PagerTable.Rows.Add(new TableRow());
PagerTable.Rows[0].Cells.Add(CellOne);
PagerTable.Rows[0].Cells.Add(cellTwo);
PagerTable.Rows[0].Cells.Add(cellThree);
PagerTable.Rows[0].Cells[0].HorizontalAlign = HorizontalAlign.Left;
PagerTable.Rows[0].Cells[1].HorizontalAlign = HorizontalAlign.Center;
PagerTable.Rows[0].Cells[2].HorizontalAlign = HorizontalAlign.Right;
row.Controls.AddAt(0, new TableCell());
row.Cells[0].ColumnSpan = columnSpan;
row.Cells[0].Controls.AddAt(0, PagerTable);
}
}
On OnRowCreated Event of the GridView
In this event, we add CheckBoxColumn
and SerialNoColumn
if required at each row.
protected override void OnRowCreated(GridViewRowEventArgs e)
{
if (e.Row.RowType != DataControlRowType.Pager)
{
if (e.Row.RowType == DataControlRowType.Header)
{
if (CheckBoxColumn)
{
HtmlInputCheckBox chkheader = new HtmlInputCheckBox();
chkheader.ID = "HeaderLevelCheckBox";
chkheader.Attributes.Add("onclick",
"ChangeAllCheckBoxStates(this.checked);");
e.Row.Cells[0].Controls.Add(chkheader);
_ArrayValues = new List<string>();
_ArrayValues.Add(string.Concat("'", chkheader.ClientID, "'"));
}
if (SerialNoColumn)
{
Label lbl = new Label();
lbl.ID = "SrNo" + e.Row.DataItemIndex + 1;
lbl.Text = "Srial No.";
e.Row.Cells[(CheckBoxColumn) ? 1 : 0].Controls.Add(lbl);
}
}
else if (e.Row.RowType == DataControlRowType.DataRow)
{
if (CheckBoxColumn)
{
HtmlInputCheckBox chkRow = new HtmlInputCheckBox();
chkRow.ID = "RowLevelCheckBox" + i++;
chkRow.Attributes.Add("onclick", "ChangeHeaderAsNeeded();");
e.Row.Cells[0].Controls.Add(chkRow);
_ArrayValues.Add(string.Concat("'", chkRow.ClientID, "'"));
}
if (SerialNoColumn)
{
Label lbl = new Label();
lbl.ID = "SrNo" + e.Row.DataItemIndex + 1;
lbl.Text = (e.Row.DataItemIndex + 1).ToString(); ;
e.Row.Cells[(CheckBoxColumn) ? 1 : 0].Controls.Add(lbl);
}
}
}
base.OnRowCreated(e);
}
Button/DropDownList Event Handlers
protected virtual void ddl_SelectedIndexChanged(object sender, EventArgs e)
{
OnPageIndexChanging(new GridViewPageEventArgs
(Convert.ToInt16(((DropDownList)sender).SelectedValue)));
}
protected void ddlPageSize_SelectedIndexChanged(object sender, EventArgs e)
{
this.PageSize = Convert.ToInt16(((DropDownList)sender).SelectedValue);
OnPageIndexChanging(new GridViewPageEventArgs(this.PageIndex));
}
protected virtual void navigate_Click(object sender, EventArgs e)
{
OnPageIndexChanging(new GridViewPageEventArgs
(int.Parse(((ImageButton)sender).CommandArgument)));
}
Other Page Information Controls
private Label PageOf()
{
Label lbl = new Label();
lbl.Text = "Page ";
return lbl;
}
private Label PageTotal()
{
Label lbl = new Label();
lbl.Text = string.Format(" of {0}", PageCount);
return lbl;
}
private Label PageInfo(int rowCount)
{
Label lbl = new Label();
int FirstRowCurrentPage = ((PageIndex * PageSize) + 1);
int LastRowCurrentPage = 0;
int LastPageIndicator = rowCount % PageSize;
LastRowCurrentPage = (PageCount == PageIndex + 1) ?
(FirstRowCurrentPage + LastPageIndicator - 1) :
(FirstRowCurrentPage + PageSize - 1);
lbl.Text = String.Format("Record {0} to {1} of {2}",
FirstRowCurrentPage, LastRowCurrentPage, rowCount);
return lbl;
}
On Load Event
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
string gridScriptPath = Page.ClientScript.GetWebResourceUrl
(this.GetType(), _gridCheck_JS);
if (!Page.ClientScript.IsClientScriptIncludeRegistered
(this.GetType(), _gridCheck_JS))
Page.ClientScript.RegisterClientScriptInclude
(this.GetType(), _gridCheck_JS, gridScriptPath);
}
On Render Event
protected override void Render(HtmlTextWriter writer)
{
writer.RenderBeginTag(HtmlTextWriterTag.Div);
if (Rows.Count > 0)
{
HtmlInputButton btn = new HtmlInputButton();
btn.ID = "SelectAllU";
btn.Value = "Select All";
btn.Attributes.Add("onclick", "ChangeAllCheckBoxStates(true);");
HtmlInputButton btn2 = new HtmlInputButton();
btn2.ID = "SelectNoneU";
btn2.Value = "Select None";
btn2.Attributes.Add("onclick", "ChangeAllCheckBoxStates(false);");
HtmlInputButton btn3 = new HtmlInputButton();
btn3.ID = "SelectAllD";
btn3.Value = "Select All";
btn3.Attributes.Add("onclick", "ChangeAllCheckBoxStates(true);");
HtmlInputButton btn4 = new HtmlInputButton();
btn4.ID = "SelectNoneD";
btn4.Value = "Select None";
btn4.Attributes.Add("onclick", "ChangeAllCheckBoxStates(false);");
btn.RenderControl(writer);
btn2.RenderControl(writer);
base.Render(writer);
btn3.RenderControl(writer);
btn4.RenderControl(writer);
}
else
{
base.Render(writer);
}
if (CheckBoxColumn)
{
Literal CheckBoxIDsArray = new Literal();
CheckBoxIDsArray.Text = "<script type="\"text/javascript\"">\n\n" +
string.Concat("var CheckBoxIDs = new Array(", string.Join
(",", _ArrayValues.ToArray()), ");") + "\n\n</script>";
CheckBoxIDsArray.RenderControl(writer);
writer.RenderEndTag();
}
}
Special Thanks to
Scott Mitchell for the
Checkbox
Column JavaScript Code