Click here to Skip to main content
12,289,383 members (32,116 online)
Click here to Skip to main content
Add your own
alternative version


98 bookmarked

ASP.NET GridView with search option (SearchableGridView)

, 12 Oct 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
An ASP.NET GridView with a search option in the footer.


I was searching for a way to include a search textbox option in the ASP.NET GridView control. I couldn’t find an elegant solution and decided to implement it myself. So here’s my solution for the problem.

Why use this solution?

You can use this solution and implement row filtering in a grid very easily. Search and filter operations can be performed by just handling the search event that is raised. In addition, this GridView also allows you to set options to show row serial numbers, total number of rows, and show the header and footer even when no rows are available in the GridView. (By default, the header and footer are hidden when the GridView has no rows to display.)

The solution

What I have done

  1. I’ve extended the GridView and created a SearchableGridView class.
  2. Added a TemplateColumn to display the row number.
  3. Added controls in the footer to handle the search operation.
  4. Raise an event with the search string as argument when a search is fired.

The code

I’ve extended the GridView control as a SearchableGridView to include the search option in the footer of the GridView.

public class SearchGridView : GridView

In order to show the row serial number, I’ve created the following template column:

public class NumberColumn : ITemplate
    public void InstantiateIn(Control container)


In SearchableGridView, I’ve overridden the OnInit function to add the template column as the first column to show the row serial number, if the ShowRowNumber flag is turned on.

protected override void OnInit(EventArgs e)
    //If showrownumber option is turned on then add 
    //the template column as the first column.
    if (!IsDesign() && ShowRowNumber) 
        TemplateField tmpCol = new TemplateField();
        NumberColumn numCol = new NumberColumn();
        tmpCol.ItemTemplate = numCol;
        // Insert this as the first column
        this.Columns.Insert(0, tmpCol);

The OnRowCreated method is called every time a row is created. During runtime, depending on the RowType, I add the search controls and the number of the row's label (in the footer), the row number (in every row), and the column header for the row number column (in the header).

protected override void OnRowCreated(GridViewRowEventArgs e)
    if (!IsDesign()) //During Runtime
        if (e.Row.RowType == DataControlRowType.Footer)
            //If ShowFooter is set to true
            if (ShowFooter && e.Row.Cells.Count > 0)
                //If TotalRows has to be shown
                if (ShowTotalRows)
                    e.Row.Cells[0].Text = ViewState[NO_OF_ROWS] + " Rows.";
                if (e.Row.Cells[e.Row.Cells.Count - 1].Controls.Count == 0)
                    //Create the search control
                    Table table = new Table();
                    table.Style.Add("width", "100%");
                    table.Style.Add("align", "right");
                    TableRow tr = new TableRow();
                    TableCell tc = new TableCell();
                    tc.Style.Add("align", "right");
                    tc.Style.Add("width", "100%");

                    //Populate the dropdownlist with the Ids
                    //of the columns to be filtered
                    if (_ddlFinder.Items.Count == 0)

                    _btnSearch.Width = 20;
                    _btnSearch.Height = 20;
                    _btnSearch.ImageAlign = ImageAlign.AbsMiddle;
                    _btnSearch.AlternateText = "Search";
                    //Assign the function that is called when search button is clicked
                    _btnSearch.Click += new ImageClickEventHandler(_btnSearch_Click);

                    e.Row.Cells[e.Row.Cells.Count - 1].Controls.Add(_pnlSearchFooter);
        if (e.Row.RowType == DataControlRowType.Header)
            // If ShowHeader is set to true and 
            // If Row number has to be shown

            if (ShowRowNumber && ShowHeader) 
                e.Row.Cells[0].Text = "Sno";
        else if (e.Row.RowType == DataControlRowType.DataRow)
            if (ShowRowNumber)
                //Set the row number in every row
                e.Row.Cells[0].Text = (e.Row.RowIndex + 
                  (this.PageSize * this.PageIndex) + 1).ToString();

The SearchFilters property of the SearchableGridView sets the dropdownlist values for the search option. The Text property of the list item corresponds to the display name in the dropdownlist and the Value property of the list item is the column name of the data source.

public void SetFilter()
    //Copy the items to the dropdownlist
    foreach (ListItem li in SearchFilters)

Now, let's move on to the handling of the search event. For this, I created a delegate and fire the event SearchGrid, when the search button is hit. The search string is formed using the syntax _ddlFinder.SelectedValue + " like '" + _tbSearch.Text.Trim() + "%'".

public delegate void SearchGridEventHandler(string _strSearch);
public event SearchGridEventHandler SearchGrid;

void _btnSearch_Click(object sender, ImageClickEventArgs e)
    string sSearchText = ConstructSearchString();

protected string ConstructSearchString()
    string _strText = _tbSearch.Text.Trim();

    if (_strText == string.Empty)
        return string.Empty;

    return _ddlFinder.SelectedValue + " like '" + _strText + "%'";

protected void OnSearchGrid(string _strSearch)
    if (SearchGrid != null)

Showing the footer when no rows are returned

The default property of the GridView is to hide the header and footer when no rows are bound to it. Setting an empty item template would only show the template but not the header or the footer. In our case, the footer has to be shown always, irrespective of the number of rows bound to the SearchableGridView, because the search option should be visible. To achieve this, I had to override the CreateChildControls method as below:

protected override int CreateChildControls(System.Collections.IEnumerable dataSource, 
                                           bool dataBinding)
    int count = base.CreateChildControls(dataSource, dataBinding);

    //  no rows in grid. create header and footer in this case
    if (count == 0 && (ShowEmptyFooter || ShowEmptyHeader))
        //  create the table
        Table table = this.CreateChildTable();

        DataControlField[] fields;
        if (this.AutoGenerateColumns)
            PagedDataSource source = new PagedDataSource();
            source.DataSource = dataSource;

            System.Collections.ICollection autoGeneratedColumns = 
                                           this.CreateColumns(source, true);
            fields = new DataControlField[autoGeneratedColumns.Count];
            autoGeneratedColumns.CopyTo(fields, 0);
            fields = new DataControlField[this.Columns.Count];
            this.Columns.CopyTo(fields, 0);

        if (ShowEmptyHeader)
            //  create a new header row
            GridViewRow headerRow = base.CreateRow(-1, -1, DataControlRowType.Header, 
            this.InitializeRow(headerRow, fields);
            // Fire the OnRowCreated event to handle showing row numbers
            OnRowCreated(new GridViewRowEventArgs(headerRow));
            //  add the header row to the table

        //  create the empty row
        GridViewRow emptyRow = new GridViewRow(-1, -1, DataControlRowType.EmptyDataRow, 
        TableCell cell = new TableCell();
        cell.ColumnSpan = fields.Length;
        cell.Width = Unit.Percentage(100);

        //  respect the precedence order if both EmptyDataTemplate
        //  and EmptyDataText are both supplied ...
        if (this.EmptyDataTemplate != null)
        else if (!string.IsNullOrEmpty(this.EmptyDataText))
            cell.Controls.Add(new LiteralControl(EmptyDataText));


        if (ShowEmptyFooter)
            //  create footer row
            GridViewRow footerRow = base.CreateRow(-1, -1, DataControlRowType.Footer, 
            this.InitializeRow(footerRow, fields);
            // Fire the OnRowCreated event to handle showing
            // search tool and total number of rows
            OnRowCreated(new GridViewRowEventArgs(footerRow));

            //  add the footer to the table


    return count;

Working sample

Let me illustrate the above control with the help of an example. For this purpose, I have used the Customers table from the NorthWind database.

Step 1: Create a data source dsCustomers with the Select query: "SELECT CustomerID, CompanyName, Address, City, Country FROM Customers".

Step 2 : Create an instance of SearchableGridView and customize the SearchFilters property to have the list of columns on which the search can be performed.

Step 3: Add two hidden fields hfSearchText and hfSort to store the search text and the sort text, respectively.

Step 4: Implement the SearchGrid event to set the search string on the data source and filter the rows in the SearchableGridView. hfSearchText and hfSort are hidden fields that hold the search string and the sort string of the SearchableGridView. The BindData method binds the data after filtering and sorting.

protected void SearchGridView1_SearchGrid(string _strSearch)
    hfSearchText.Value = _strSearch;

protected void SearchGridView1_Sorting(object sender, GridViewSortEventArgs e)
    //If hfSort has the same value as before, 
    //the sorting should be done in descending order
    if (hfSort.Value == e.SortExpression)
        hfSort.Value = e.SortExpression + " Desc";
        hfSort.Value = e.SortExpression;

void BindData()
    //hfSearchText has the search string returned from the grid.
    if (hfSearchText.Value != "")
        dsCustomers.SelectCommand += " where " + hfSearchText.Value;
    DataView dv = (DataView)dsCustomers.Select(new DataSourceSelectArguments());
    //hfSort has the sort string returned from the grid.
    if (hfSort.Value != "")
        dv.Sort = hfSort.Value;

    SearchGridView1.DataSource = dv;
    catch (Exception exp)
        //If databinding threw exception b’coz current 
        //page index is > than available page index
        SearchGridView1.PageIndex = 0;
        //Select the first row returned
        if (SearchGridView1.Rows.Count > 0)
            SearchGridView1.SelectedIndex = 0;


SearchableGridView will be very useful when there are a large number of rows in the grid. Searching through the rows can be implemented without much hassle.


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


About the Author

Aparna Lakshminarayanan
Software Developer (Senior)
India India
She has been working on .Net since 2005. Has recently started working on AJAX and ASP .NET and just Loves this technology!

You may also be interested in...

Comments and Discussions

GeneralNice work. Pin
Deb-Samrat7-Aug-14 5:45
memberDeb-Samrat7-Aug-14 5:45 
QuestionHow to use Search function gridview Pin
Anil Srivastava22-Feb-14 19:49
memberAnil Srivastava22-Feb-14 19:49 
QuestionWhats wrong in this search query? Pin
Ruhani1820-Feb-14 17:28
memberRuhani1820-Feb-14 17:28 
GeneralMy vote of 3 Pin
Member 1045209629-Dec-13 0:43
memberMember 1045209629-Dec-13 0:43 
QuestionModifing this control Pin
Adrian Viegas1-May-13 3:56
memberAdrian Viegas1-May-13 3:56 
QuestionHelp.. Pin
Member 942577125-Oct-12 9:43
memberMember 942577125-Oct-12 9:43 
GeneralMy vote of 5 Pin
John Bhatt19-Sep-12 20:01
memberJohn Bhatt19-Sep-12 20:01 
Generalits pitty Pin
s.shukla19-Sep-12 1:50
members.shukla19-Sep-12 1:50 
GeneralMy vote of 5 Pin
Aamer Alduais7-Jul-12 20:09
memberAamer Alduais7-Jul-12 20:09 
QuestionExcellent work Pin
richgov_200324-Jun-12 3:41
memberrichgov_200324-Jun-12 3:41 
GeneralMy vote of 5 Pin
Prasad_Kulkarni3-Jun-12 22:59
memberPrasad_Kulkarni3-Jun-12 22:59 
QuestionVery good sample Pin
Xiayi5927-Apr-12 10:12
memberXiayi5927-Apr-12 10:12 
GeneralMy vote of 5 Pin
ProEnggSoft8-Mar-12 15:25
memberProEnggSoft8-Mar-12 15:25 
QuestionHelp Pin
SakyASP28-Jan-12 6:12
memberSakyASP28-Jan-12 6:12 
GeneralMy vote of 5 Pin
BRICKCAP5-Nov-11 19:23
memberBRICKCAP5-Nov-11 19:23 
QuestionCool... Just One Thing... Pin
Anurag Gandhi22-Sep-11 20:19
memberAnurag Gandhi22-Sep-11 20:19 
GeneralCould you check this implementation ? Pin
Juan T. Llibre7-Jun-11 11:14
memberJuan T. Llibre7-Jun-11 11:14 
GeneralNice article... Pin
Sandeep Mewara28-Nov-10 8:57
mentorSandeep Mewara28-Nov-10 8:57 
GeneralRe: Nice article... Pin
Aparna Lakshminarayanan2-Dec-10 0:24
memberAparna Lakshminarayanan2-Dec-10 0:24 
GeneralHelp [modified] Pin
leopete26-Oct-10 3:07
memberleopete26-Oct-10 3:07 
GeneralRe: Help Pin
Aparna Lakshminarayanan2-Dec-10 0:24
memberAparna Lakshminarayanan2-Dec-10 0:24 
Generali am geting error !!! Pin
dasdex9-Jul-10 0:09
memberdasdex9-Jul-10 0:09 
GeneralRe: i am geting error !!! Pin
Aparna Lakshminarayanan2-Aug-10 7:41
memberAparna Lakshminarayanan2-Aug-10 7:41 
GeneralMy vote of 5 Pin
secured29-Jun-10 23:29
membersecured29-Jun-10 23:29 
sushilbondre8-Jun-10 22:42
membersushilbondre8-Jun-10 22:42 
Questionsearch control do no appear when use template field in datagrid Pin
Ne7ven26-Mar-10 0:37
memberNe7ven26-Mar-10 0:37 
AnswerRe: search control do no appear when use template field in datagrid Pin
Aparna Lakshminarayanan2-Aug-10 7:45
memberAparna Lakshminarayanan2-Aug-10 7:45 
GeneralQuestions about Searchable Gridview Pin
Sid Childers4-Feb-10 10:23
memberSid Childers4-Feb-10 10:23 
GeneralRe: Questions about Searchable Gridview Pin
Aparna Lakshminarayanan2-Aug-10 7:49
memberAparna Lakshminarayanan2-Aug-10 7:49 
GeneralNice Work ! Pin
Abhijit Jana19-Nov-09 0:25
mvpAbhijit Jana19-Nov-09 0:25 
GeneralRe: Nice Work ! Pin
Aparna Lakshminarayanan3-Dec-09 16:09
memberAparna Lakshminarayanan3-Dec-09 16:09 
GeneralGreat customed control Pin
nicholas_pei27-Oct-09 22:14
membernicholas_pei27-Oct-09 22:14 
GeneralRe: Great customed control Pin
Aparna Lakshminarayanan3-Nov-09 17:29
memberAparna Lakshminarayanan3-Nov-09 17:29 
GeneralNice Pin
Muneeb R. Baig19-Oct-09 19:20
memberMuneeb R. Baig19-Oct-09 19:20 
GeneralRe: Nice Pin
Aparna Lakshminarayanan19-Oct-09 19:41
memberAparna Lakshminarayanan19-Oct-09 19:41 
GeneralDon't swallow exceptions. Pin
N a v a n e e t h13-Oct-09 18:12
mvpN a v a n e e t h13-Oct-09 18:12 
GeneralRe: Don't swallow exceptions. Pin
Aparna Lakshminarayanan14-Oct-09 7:39
memberAparna Lakshminarayanan14-Oct-09 7:39 
General... Pin
martyn_mcfly13-Oct-09 5:13
membermartyn_mcfly13-Oct-09 5:13 
GeneralRe: ... Pin
Aparna Lakshminarayanan14-Oct-09 7:43
memberAparna Lakshminarayanan14-Oct-09 7:43 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160518.1 | Last Updated 12 Oct 2009
Article Copyright 2009 by Aparna Lakshminarayanan
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid