Tuesday, May 22, 2012

ASP.NET - Efficiently Hide GridView Columns using Column names.

I've seen several places on the web that illustrate how to hide Columns of a GridView based on Column number rather than Column name. After poking around a bit and a fellow developer pushed me in the right direction, I found a cleaner approach using column names.

This blog post however assumes that the DataSource of the GridView is a DataTable. Which means that when Binding data to the GridView its DataSource Property is set to a DataTable object.

 For Example:


DataTable dt = /* Taken from already formatted Column Named Table */;
gridView.DataSource = dt;
gridView.DataBind();


It also assumes that the DataTable has already been formatted with appropriate Header/Column Names.

First,  before the DataTable is bound like in the code above, a Dictionary object should be created to store both Column Names and Column Indices.  This is done using the Ordinal member variable of the DataTable:


Dictionary<string,int> hideIndices = new Dictionary<string,int>();

hideIndices.Add("NAME", dt.Columns["NAME"].Ordinal);


hideIndices.Add("Description", dt.Columns["Description"].Ordinal);

The above Columns are then "NAME" and "Description" respectively.

Now the hideIndices object needs to be saved (due to the Postback behavior of asp.net) to a Session variable.


Session.Add("hideIndices", hideIndices);


Finally, These columns can be hidden in the RowCreated event handler assigned to the gridView.  The indices can be looped through in the dictionary in order to make each Cell that corresponds to all indices in the saved list invisible (Visible property = false).

protected void gridView_RowCreated(object sender, GridViewRowEventArgs e){
    if (Session["hideIndices"] != DBNull.Value)
    {
         Dictionary<string, int> hideIndices = 
         (Dictionary<string,  int>)Session["hideIndices"];
         
         foreach (int index in hideIndices.Values)
         {
               e.Row.Cells[index].Visible = false;
         }
     }
}
That should effectively hide all columns in a gridview based on column name.  Notice however that a List<int> object would have worked just as well for this example.  I however left it as a Dictionary object incase of further need of the Column name else where.