Monday, March 7, 2011

Scrollable Gridview with Freeze header and sort image.



AntonioSuarez_gridview_ff.JPGAntonioSuarez_gridview_ie.JPG

Introduction

I was searching for a way to get a scrollable Gridview with a freeze header and I found different ways to do it, but most of them use CSS or JavaScript. What I want to find was a way to do it in the code file. (.CS or .VB)
Here I would try to explain how it could be done with code. (.CS)

Using the Code

You just need to add a Panel control then add a Table and Gridview control inside of Panel control.
in the .CS file you need to add this code:

AddSortDirectionImage Function

Collapse
/// summary
    ///   Email: Antonio.Suarez@GrupoKino.com
    ///Web Page: http://www.grupoKino.com    
    /// [Español]Funcion que agrega una imagen a la columna ordenada de un gridView 
    /// [English]Function that adds a image to the sorted column.
    /// summary
    /// param name="gridviewID"
    /// [Español]Gridview al cual se le agregara la imagen 
    /// [English]GridView to add sort image
    /// param
    /// param name="itemRow"
    /// [Español]Renglon del gridview al cual se le agrega la imagen 
    /// [English]Row of gridview to add sort image
    /// param

    public void AddSortDirectionImage(GridView gridviewID, GridViewRow itemRow)
    {
        if (gridviewID.AllowSorting == false)
            return;

        Image sortImage = new Image();
        Label space = new Label();

        sortImage.ImageUrl = (
            gridviewID.SortDirection ==
            SortDirection.Ascending ? @"~/sort_asc.gif" : @"~/sort_desc.gif");
        sortImage.Visible = true;
        space.Text = " ";


        for (int i = 0; i < gridviewID.Columns.Count; i++)
        {
            string colExpr = gridviewID.Columns[i].SortExpression;
            if (colExpr != "" && colExpr == gridviewID.SortExpression)
            {
                itemRow.Cells[i].Controls.Add(space);
                itemRow.Cells[i].Controls.Add(sortImage);
            }
        }
    }

And FreezeGridviewHeader Function

Collapse
/// summary
    ///  Author: Antonio Suarez
    ///   Email: Antonio.Suarez@GrupoKino.com
    ///Web Page: http://www.grupoKino.com    
    /// [Español]Funcion que copia el header de un gridview a un control tipo Table 
    /// [English]Function that copy a gridview header to a table control.
    /// summary
    /// param name="_gv1"
    /// [Español]Gridview del cual se copiara el encabezado.
    /// [English]GridView from where the header row will be copied
    /// param
    /// param name="_tb1"
    /// [Español]Renglon del gridview al cual se le agrega la imagen 
    /// [English]Row of gridview to add sort image
    /// 
    /// param name="_pc1"
    /// [Español]Panel que contendra tanto al gridview como al control table
    /// [English]Panel container of the gridview and table control.   
    /// param    
    protected void FreezeGridviewHeader(GridView _gv1, Table _tb1,Panel _pc1)
    {
        Page.EnableViewState = false;

        //[Español]Copiando las propiedades del renglon de encabezado
        //[English]Copying a header row data and properties    
        _tb1.Rows.Add(_gv1.HeaderRow);
        _tb1.Rows[0].ControlStyle.CopyFrom(_gv1.HeaderStyle);
        _tb1.CellPadding = _gv1.CellPadding;
        _tb1.CellSpacing = _gv1.CellSpacing;
        _tb1.BorderWidth = _gv1.BorderWidth;

        //if (!_gv1.Width.IsEmpty)
        //_gv1.Width = Unit.Pixel(Convert.ToInt32(_gv1.Width.Value) + Convert.ToInt32(
        //    _tb1.Width.Value) + 13);

        //[Español]Copiando las propiedades de cada celda del nuevo encabezado.
        //[English]Copying  each cells properties to the new header cells properties
        int Count = 0;
        _pc1.Width = Unit.Pixel(100);
        for (Count = 0; Count < _gv1.HeaderRow.Cells.Count - 1; Count++)
        {
            _tb1.Rows[0].Cells[Count].Width = _gv1.Columns[Count].ItemStyle.Width;
            _tb1.Rows[0].Cells[Count].BorderWidth = 
                _gv1.Columns[Count].HeaderStyle.BorderWidth;
            _tb1.Rows[0].Cells[Count].BorderStyle = 
                _gv1.Columns[Count].HeaderStyle.BorderStyle;
            _pc1.Width = Unit.Pixel(Convert.ToInt32(
                _tb1.Rows[0].Cells[Count].Width.Value) +
                Convert.ToInt32(_pc1.Width.Value) + 14);
        }
        //Panel1.Width = Unit.Pixel(Convert.ToInt32(
        //    _tb1.Rows[0].Cells[Count-1].Width.Value) + 12);
    }
 
in web.config
-----------------
<?xml version="1.0"?>
<configuration>
 <configSections>
  <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
   <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
    <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
    <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
     <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="Everywhere"/>
     <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
     <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
    </sectionGroup>
   </sectionGroup>
  </sectionGroup>
 </configSections>
 <connectionStrings>
  <add name="NorthwindConnectionString" connectionString="Data Source=.;Initial Catalog=Northwind;Integrated Security=True" providerName="System.Data.SqlClient"/>
 </connectionStrings>
 <system.web>
  <pages>
   <controls>
    <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
   </controls>
  </pages>
  <!--
          Set compilation debug="true" to insert debugging
          symbols into the compiled page. Because this
          affects performance, set this value to true only
          during development.
    -->
  <compilation debug="true">
   <assemblies>
    <add assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
   </assemblies>
  </compilation>
  <httpHandlers>
   <remove verb="*" path="*.asmx"/>
   <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
   <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
   <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/>
  </httpHandlers>
  <httpModules>
   <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
  </httpModules>
 </system.web>
 <system.webServer>
  <validation validateIntegratedModeConfiguration="false"/>
  <modules>
   <add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
  </modules>
  <handlers>
   <remove name="WebServiceHandlerFactory-Integrated"/>
   <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
   <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
   <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
  </handlers>
 </system.webServer>
</configuration>
 
masterpage.master
---------------
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Antonio.Suarez@grupoKino.com - Gridview</title>
</head>
<body>
    <form id="form1" runat="server">
        <table border="0" cellpadding="0" cellspacing="0" style="width: 100%">
            <tr>
                <td style="font-size: 1.5em; color: blue; font-family: verdana">
                    <asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
                        Scrollable Gridview with Freeze header and sort image that works inside and outside of UpdatePanel.
                        It works in Firefox and Internet Explorer too.
                        <br />
                    </asp:contentplaceholder>
                </td>
            </tr>
            <tr>
                <td>
                    <asp:ContentPlaceHolder ID="ContentPlaceHolder2" runat="server">
                    </asp:ContentPlaceHolder>
                </td>
            </tr>
        </table>
    </form>
</body>
</html>
 
in default.aspx
------------------
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;


/// <summary>
///  Author: Antonio Suarez
///   Email: Antonio.Suarez@GrupoKino.com
///Web Page: http://www.grupoKino.com
/// </summary>

public partial class _Default : System.Web.UI.Page
{
    #region Global Variables

    #endregion

    protected void Page_Load(object sender, 

EventArgs e)
    {

        if (!IsPostBack)
            FreezeGridviewHeader(GridView1, _tb, 

PanelContainer);
    }






    #region GridView1 Functions

    protected void GridView1_RowDataBound(object 

sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType ==  

DataControlRowType.DataRow)
            if (e.Row.RowIndex == 1)
                FreezeGridviewHeader

(GridView1,_tb,PanelContainer);
    }
    protected void GridView1_RowCreated(object 

sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == 

DataControlRowType.Header)
            AddSortDirectionImage(GridView1, 

e.Row);
    }

    #endregion


    #region GridView1 Functions
      protected void GridView2_RowDataBound(object 

sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == 

DataControlRowType.DataRow)
            if (e.Row.RowIndex == 1)
                FreezeGridviewHeader(GridView2, 

_tb2, PanelContainer2);
    }  

    protected void GridView2_RowCreated(object 

sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == 

DataControlRowType.Header)
            AddSortDirectionImage(GridView2, 

e.Row);
    }    

    #endregion

    /// <summary>
    ///  Author: Antonio Suarez
    ///   Email: Antonio.Suarez@GrupoKino.com
    ///Web Page: http://www.grupoKino.com    
    /// [Español]Funcion que copia el header de un 

gridview a un control tipo Table 
    /// [English]Function that copy a gridview 

header to a table control.
    /// </summary>
    /// <param name="_gv1">
    /// [Español]Gridview del cual se copiara el 

encabezado.
    /// [English]GridView from where the header 

row will be copied
    /// </param>
    /// <param name="_tb1">
    /// [Español]Renglon del gridview al cual se 

le agrega la imagen 
    /// [English]Row of gridview to add sort image
    /// </param>
    /// <param name="_pc1">
    /// [Español]Panel que contendra tanto al 

gridview como al control table
    /// [English]Panel container of the gridview 

and table control.   
    /// </param>     
    protected void FreezeGridviewHeader(GridView 

_gv1, Table _tb1,Panel _pc1)
    {
        Page.EnableViewState = false;

        //[Español]Copiando las propiedades del 

renglon de encabezado
        //[English]Coping a header row data and 

properties    
        _tb1.Rows.Add(_gv1.HeaderRow);
        _tb1.Rows[0].ControlStyle.CopyFrom

(_gv1.HeaderStyle);
        _tb1.CellPadding = _gv1.CellPadding;
        _tb1.CellSpacing = _gv1.CellSpacing;
        _tb1.BorderWidth = _gv1.BorderWidth;

        //if (!_gv1.Width.IsEmpty)
        //_gv1.Width = Unit.Pixel(Convert.ToInt32

(_gv1.Width.Value) + Convert.ToInt32

(_tb1.Width.Value) + 13);

        //[Español]Copiando las propiedades de 

cada celda del nuevo encabezado.
        //[English]Coping  each cells properties 

to the new header cells properties
        int Count = 0;
        _pc1.Width = Unit.Pixel(100);
        for (Count = 0; Count < 

_gv1.HeaderRow.Cells.Count - 1; Count++)
        {
            _tb1.Rows[0].Cells[Count].Width = 

_gv1.Columns[Count].ItemStyle.Width;
            _tb1.Rows[0].Cells[Count].BorderWidth 

= _gv1.Columns[Count].HeaderStyle.BorderWidth;
            _tb1.Rows[0].Cells[Count].BorderStyle 

= _gv1.Columns[Count].HeaderStyle.BorderStyle;
            _pc1.Width = Unit.Pixel

(Convert.ToInt32(_tb1.Rows[0].Cells

[Count].Width.Value) + Convert.ToInt32

(_pc1.Width.Value) + 14);
        }
        //Panel1.Width = Unit.Pixel

(Convert.ToInt32(_tb1.Rows[0].Cells[Count-

1].Width.Value) + 12);
    }


    /// <summary>
    ///  Author: Antonio Suarez
    ///   Email: Antonio.Suarez@GrupoKino.com
    ///Web Page: http://www.grupoKino.com    
    /// [Español]Funcion que agrega una imagen a 

la columna ordenada de un gridView 
    /// [English]Function that adds a image to the 

sorted column.
    /// </summary>
    /// <param name="gridviewID">
    /// [Español]Gridview al cual se le agregara 

la imagen 
    /// [English]GridView to add sort image
    /// </param>
    /// <param name="itemRow">
    /// [Español]Renglon del gridview al cual se 

le agrega la imagen 
    /// [English]Row of gridview to add sort image
    /// </param>
    public void AddSortDirectionImage(GridView 

gridviewID, GridViewRow itemRow)
    {
        if (gridviewID.AllowSorting == false)
            return;

        Image sortImage = new Image();
        Label space = new Label();

        sortImage.ImageUrl = 

(gridviewID.SortDirection == 

SortDirection.Ascending ? @"~/sort_asc.gif" : 

@"~/sort_desc.gif");
        sortImage.Visible = true;
        space.Text = " ";


        for (int i = 0; i < 

gridviewID.Columns.Count; i++)
        {
            string colExpr = gridviewID.Columns

[i].SortExpression;
            if (colExpr != "" && colExpr == 

gridviewID.SortExpression)
            {
                itemRow.Cells[i].Controls.Add

(space);
                itemRow.Cells[i].Controls.Add

(sortImage);
            }
        }
    }
}
 
add to .gif file(sort_desc.gif and sort_Asc .gif)

No comments:

Post a Comment