How To Expand/Collapse Columns in ASP.NET GridView? - Part IV
Bookmark
 

Rating: 5.00/5
1 2 3 4 5
1 people have rated this article

 
Posted On: Apr 22 2009
Views: 2531
BookMarked: 0
Downloads: 180
 
 

 

In the previous article we discussed about creating a custom drill down nested gridview.

Sometimes, we need to display more than 20 columns in a gridview. Obiviously this would mess up our website design or would place horizontal scroll bar on th epage. It would be great if gridview has a toggle button on the gridview header to hide part of the header cells.

if we have crystal report like toggle buttons on the gridview header will give an appealing design.

In this article we are going to see how to implement toggle buttons/ expand.collapse buttons on the grid view header.

 

Create Your Own Custom Control

So our very first step is creating a class file and inherits GridView Class.

namespace CustomControls
{
      public class ToggleGridView: GridView
      {
           public ToggleGridView()
           {
           }
     }
}

 

Toggle Column or Cell

Toggle Column is a header cell which has collapsible button to show/hide header cells on the mouse click. It should be a comma separated header cell values.

ToggleColumns Property

Add the following to ToggleGridView class. During page load, the Toggle Columns are split into integer array.

private string _toggleColumns;

        public String ToggleColumns

        {

            get { return _toggleColumns; }

            set

            {

                _toggleColumns = value;

                LoadToggleColumns(_toggleColumns);

            }

        }

       

       private int[] _toggleColumnsArray;

      

Following method is used to load the integer array from ToggleColumns property.

private void LoadToggleColumns(String showHideColumns)

{

 

          String[] toggleColumns = showHideColumns.Split(',');

 int intCol = 0, count = 0;

            for (int index = 0; index < toggleColumns.Length;index++)

            {

              

                if (Int32.TryParse(toggleColumns[index], out intCol))

                {

                    Array.Resize(ref _toggleColumnsArray, index + 1);

                    _toggleColumnsArray[count] = intCol;

                    count++;

                }

                else

                    throw new Exception("ToggleColumns propery must

have comma separated integers.");

            }

            Array.Sort(_toggleColumnsArray);

}

How it works?

For instance, a GridView has a total of 10 columns to display and we set ToggleColumns as 2,6. 

ToggleGridview will display 1st cell,2nd cell with collapsible button,6th cell with collapsible button .

The cells after 2nd header column will be hidden. Since we have one more toggle column #6, grid will provide one more collapsible button on 6th cell and leaving other cells hidden.

Following method will tell you whether given cell has configured as collapsible button . It also returns  start and end of the hidden columns if the given cell is present in the ToggleColumns property.

private bool IsShowHideButtonCell(int cell, out int lowerBound

, out int upperBound)

        {

            lowerBound = upperBound = 0;

            for (int i = 0; i < _toggleColumnsArray.Length; i++)

            {

                if (_toggleColumnsArray[i] == cell + 1)

                {

                    lowerBound = _toggleColumnsArray[i] - 1;

                    if (i == _toggleColumnsArray.Length - 1)

                        upperBound = this.HeaderRow.Cells.Count - 1;

                    else

                        upperBound = _toggleColumnsArray[i + 1] - 2;

                    if (lowerBound != upperBound)

                        return true;

                }

            }

            return false;

        }

 

 To find the visibility of the Data Cells(Body of the GridView), the following method is used.

 

private bool IsCellHidden(int cell)

        {         

            for (int i = 0; i < _toggleColumnsArray.Length; i++)

            {

                if (cell == _toggleColumnsArray[i] - 1)

                    return false;

            }

 

            return true;

        }

 

OnRowCreated() Event

.NET 2.0 framework offers lot of new features. We are going to use the new .Net 2.0 feature OnRowCreated method to render our extra header.
Before GridView control can be rendered,a GridView Row object must be created for each row.The RowCreated event is raised when each row of the GridView control is created. This enables you provide your own event handling method that adds extra content to the rows. This is the preferred method for modifying GridView in the derived class. For those who are using old versions, override OnDataBound or OnRowDataBound method in the derived class to create a custom routine. But disadvantage is griview does not keep the extra header after the postback.

//This method is new in the .NET Framework version 2.0.

        protected override void OnRowCreated(GridViewRowEventArgs e)

        {

            if (e.Row.RowType == DataControlRowType.Header)

            {

                if (_toggleColumnsArray!=null && _toggleColumnsArray.Length > 0)

            {

                //Represents the method that renders the specified Control container to the specified HtmlTextWriter.

                e.Row.SetRenderMethodDelegate(ShowHideHeaderCells);

                 }

            }

            if (e.Row.RowType == DataControlRowType.DataRow)

            {

                if (_toggleColumnsArray != null && _toggleColumnsArray.Length > 0)

            {

                //Represents the method that renders the specified Control container to the specified HtmlTextWriter.

                e.Row.SetRenderMethodDelegate(ShowHideDataCells);

                }

            }

            // When overriding OnRowCreated in a derived class, be sure to call the base class's

            //OnRowCreated method so that registered delegates receive the event.      

            base.OnRowCreated(e);

        }
When override OnRowCreated Method,we have to call the base’s class OnRowCreated method.So that our registered delegates will receive the event.

SetRenderMethodDelegate() Method To Perform Custom Routine

To perform custom routine such as adding additional header to the GridView, we use the Control.SetRenderMethodDelegate(CreateExtraHeader) method. This method assigns an event handler delegate to render the server control and its content into its parent control.

 e.Row.SetRenderMethodDelegate(YourRenderMethod).

It represents the method that renders the specified Control container to the specified HtmlTextWriter.


Render Method

Your render method will be:

private void ShowHideHeaderCells(HtmlTextWriter PageOutput, Control HeadContainer)

        {

           

                //Now render default header/2nd header   

                for (int i = 0; i < HeadContainer.Controls.Count; i++)

                {

                    TableCell cell = (TableCell)HeadContainer.Controls[i];

                    int lowerBound = 0; int upperBound = 0;

                    if (IsShowHideButtonCell(i, out lowerBound, out upperBound))

                    {

                        HtmlAnchor DrillDownAnchor = new HtmlAnchor();                       

                        DrillDownAnchor.Attributes["onclick"] =

"ToggleTableCells('" + this.ClientID + "',this," + lowerBound + "," + upperBound + ")";

                        DrillDownAnchor.InnerText = "+";

                        DrillDownAnchor.Attributes["class"] = "ToggleAnchorTag";

                        cell.Controls.AddAt(0, DrillDownAnchor);

                        Literal lt = new Literal();

                        lt.Text = cell.Text;

                        cell.Controls.AddAt(1, lt);

                    }

                    if (IsCellHidden(i))

                    {

                        cell.Attributes["style"] = "display:none;";

                    }

                    cell.RenderControl(PageOutput);

                }

        }

 JavaScript To Toggle GridView Columns

Following JavaScript is used to hide and show the header cells. It accepts grid view ID, start of hidden cell and end of hidden cell. This onclick method is added to each cell in the ToggleColumns property.

function ToggleTableCells(gridId,me,startCell,endCell){

    //Firefox doesn't render display property (block) for tables..so don't use display.

    var cellDisplay = '';

    var table  = document.getElementById(gridId);

    var rows = table.getElementsByTagName('tr');

 

    if(getText(me)=='+'){    

        cellDisplay = '';

        setText(me,'-');

     }

     else{    

        cellDisplay = 'none';

        setText(me,'+');

     }

    for (var row=0; row<rows.length;row++){   

        var headCells = rows[row].getElementsByTagName('th');

        for(var headCell=0;headCell<headCells.length;headCell++){

            if(headCell>startCell && headCell<=endCell)

                headCells[headCell].style.display=cellDisplay;

          

        }

         var dataCells = rows[row].getElementsByTagName('td');

         for(var dataCell=0;dataCell<dataCells.length;dataCell++){

            //alert(dataCell+','+startCell+','+endCell);

            if(dataCell>startCell && dataCell<=endCell)

                dataCells[dataCell].style.display=cellDisplay; 

                   

         }    

    } 

}

 

FYI: Firefox bug fixed.

Please check other articles on Custom Gridviews and don't forget to rate the article. Your feedback is important.

 



Rate This Article

Please Sign In In to post messages.