Custom Gridveiw Control with Custom Pager, Check Box Column, Serial Number Column, Custom Navigation






4.33/5 (6 votes)
This article contains Custom Gridview Control with added features like Custom Pager Navigation Controls, custom Page Size with Drop Down List, Check Box Column, Serial Number Column
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 ofgridview
- 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 passCommandargument
,DropdownValue
as argument togridview
spageindex
changing event.
- Create 4 image buttons with properties
- In the second cell, we show Grid information in labels.
- In the third cell, we create
dropdown
list with custom page size, attacheventhandler
to selected index change and setpagesize
. - Create
Checkbox
columns and Serial Number Columns- Override
OnRowCreated
method - Check for created row is Header, or
datarow
- Check if
CheckboxColumn
andSerialNoColumn
property is set totrue
- If it is
true
then in Header row write Header for Check Box first, and then Serial - If it is
datarow
, then createRowLevelCheckboxes
- Override
- 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 Checkbox column is required, then Add New Boundfield
//into the gridview row at index 0.
if (CheckBoxColumn)
{
this.Columns.Insert(0, new BoundField());
}
}
}
Enables/Disables SR. No. Column
public bool SerialNoColumn
{
get
{
return _SrNoColumn;
}
set
{
_SrNoColumn = value;
//if SerialNoColumn is required, then Add New Boundfield
//into the gridview row at index 0.
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)
{
//Checking the type of pager Custom or Default.
if (!CustomPageing)
{
//The pager will be initialized to default.
//if we don't want it in the usual way
base.InitializePager(row, columnSpan, pagedDataSource);
}
else
{
//Custom Pager
//Each time we add 1 to columnSpan when properties for
//CheckBoxColumn and SerialNoColumn are set to true
if (CheckBoxColumn) { columnSpan += 1; }
if (SerialNoColumn) { columnSpan += 1; }
//Creating Controls
//Creating DropdownList to Show No of pages in the GridView.
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()));
}
//We have to new Add Eventhandler to change page
//index on selecting Page number from the Gridview
ddl.SelectedIndexChanged += new EventHandler(ddl_SelectedIndexChanged);
ddl.SelectedIndex = PageIndex;
//Creating DropdownList having Page size
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()));
//add Event Handler to it
ddlPageSize.SelectedIndexChanged +=
new EventHandler(ddlPageSize_SelectedIndexChanged);
//Creating Image Buttons for navigation and setting its page index,
//attach eventhandlers for Click
ImageButton first = new ImageButton();
first.AlternateText = "|<< First ";
//If we do not give image or left blank then
//it will automatically assign default image.
first.ImageUrl = (FirstImage == string.Empty) ?
Page.ClientScript.GetWebResourceUrl(typeof(InderGrid),
"Indrajeet.Web.UI.WebControls.First.gif") : FirstImage;
//Fist button always has Page index 0
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;
//Previous button always has Page Index= Page index -1
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;
//Previous button always has Page Index= Page index +1
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 Button always has Last Page index so it is Page count -1
last.CommandArgument = string.Format("{0}", (PageCount - 1));
last.Enabled = (PageIndex < (PageCount - 1));
last.Click += new ImageClickEventHandler(navigate_Click);
//New Creating Table with Tree Cells.
//First Cell contains Paging Navigation Control
//i.e. First, Next, DropDown for Current Page and Next, Last Record
//Second Cell contains Paging Summary.
//Third Cell will contain The Page Size.
//Crate a Table Cell One and Add Navigation Controls to it.
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);
//Create Cell Two
TableCell cellTwo = new TableCell();
cellTwo.Controls.Add(PageInfo(pagedDataSource.DataSourceCount));
//
TableCell cellThree = new TableCell();
cellThree.Controls.Add(ddlPageSize);
//Create Table and row and add cells in to that Row.
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;
//Now Add this table to GridViewRow
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)
{
//Checking Rowtype
if (e.Row.RowType != DataControlRowType.Pager)
{
//Add header Columns for Checkbox and Serial No
if (e.Row.RowType == DataControlRowType.Header)
{
//Render Checkbox control if CheckBoxColumn is true
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, "'"));
}
//Render Serial Number Column if SerialNoColumn is true
if (SerialNoColumn)
{
Label lbl = new Label();
lbl.ID = "SrNo" + e.Row.DataItemIndex + 1;
lbl.Text = "Srial No.";
//Checkbox column is set to first so check if,
//checkboxColumn is present then SerialNoColumn
//will be second else first
e.Row.Cells[(CheckBoxColumn) ? 1 : 0].Controls.Add(lbl);
}
}
//Add DataRows for checkbox and SerialNoColumn
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)));
}
//For Pagesize set pagesize to DropDownLists SelectedValue and
//raise GridView's OnPageIndexChanging method and pass currentpage index to it
protected void ddlPageSize_SelectedIndexChanged(object sender, EventArgs e)
{
this.PageSize = Convert.ToInt16(((DropDownList)sender).SelectedValue);
OnPageIndexChanging(new GridViewPageEventArgs(this.PageIndex));
}
//On Click Event of Navigation Button
//we have to pass CommandArgument as argument
//to GridView's OnPageIndexChanging method
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;
}
//For showing GridView's Page Count
private Label PageTotal()
{
Label lbl = new Label();
lbl.Text = string.Format(" of {0}", PageCount);
return lbl;
}
//For Displaying Current Record
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);
//Calling Javascript file
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)
{
//Creating Javascript Array of Gridview Checkbox
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 theCheckbox
Column JavaScript Code