Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

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

4.33/5 (6 votes)
7 Apr 2010CPOL3 min read 1   2.8K  
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.

GVCustomPager02.JPG

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 gridviews 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
GVCustomPager01.JPG

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
CustomPageingBoolean Enables/Disables custom paging
CheckBoxColumnBooleanEnables/Disables CheckBox Column
SerialNoBooleanEnables/Disables SR. No. Column
FirstImageStringSets/Gets Images path to First Navigation Button
NextImageStringSets/Gets Images path to Next Navigation Button
PreviousImage StringSets/Gets Images path to Previous Navigation Button
LastImageStringSets/Gets Images path to Last Navigation Button

Setting Properties

Enables/Disables Custom Paging

C#
public bool CustomPageing
       {
           get { return _CustomPageing; }
           set { _CustomPageing = value; }
       }

Enables/Disables CheckBox Column

C#
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

C#
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

C#
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:

C#
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.

C#
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

C#
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

C#
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

C#
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

C#
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 the Checkbox Column JavaScript Code

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)