This is a simple trick that came into my mind working on a legacy ASP.NET application, the scenario is: we have a series of components that use a GridView to show some data, each GridView have several columns and according to the situation some have to be hidden and some shown (depending on the client configuration).
The problem here is that you can access the GridView.Columns[] collection using only an integer indexer, the implementation I found just stored in the database a list of the integer corresponding to the columns to hide, and use a for cycle to do the job:
For Each id As Integer In indexes
gv.Columns(id).Visible = False
Next
It works, but it have a major drawback...if you add or remove columns from the control you have to update the index list...and if the application stores the information for each customer or user...that goes for all of them too.
The solution is simple, we just want to add an ID string field to the BoundField, TemplateField, etc...that a GridView uses to define its columns, to do the job we can inherit from those classes and add the required behaviour. We do not have multiple inheritance, so we are forced to use an interface to give a common aspect to all our inherited classes.
public interface IExtendedBoundField
{
string Id { get; set; }
}
public class ExtendedBoundField : BoundField, IExtendedBoundField
{
public string Id { get; set; }
}
public class ExtendedTemplateField : TemplateField, IExtendedBoundField
{
public string Id { get; set; }
}
The Asp.NET code that uses this new fields will be like:
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AutoGenerateColumns="False"
PageSize="30" DataKeyNames="cvcr_id" meta:resourcekey="GridView1Resource1" AllowSorting="True">
<Columns>
<avc:ExtendedBoundField Id="cognome" HeaderText="Cognome" DataField="cvcr_surname" SortExpression="cvcr_surname"
meta:resourcekey="BoundFieldResource2" />
<avc:ExtendedBoundField Id="nome" DataField="cvcr_name" SortExpression="cvcr_name" HeaderText="Nome"
meta:resourcekey="BoundFieldResource3" />
<avc:ExtendedTemplateField Id="eta" HeaderText="Età" SortExpression="age">
<ItemTemplate>
<asp:Label ID="lblAge" runat="server" Text='<%# Databinder.Eval(Container.DataItem, "age") %>'
ToolTip='<%# Databinder.Eval(Container.DataItem,"cvcr_birthdate", "{0:dd/MM/yyyy}") %>'></asp:Label>
</ItemTemplate>
</avc:ExtendedTemplateField>
...
In the end you need to write an extension method that allows you to access the DataControlField given the Id
public static class GridViewExtensions
{
public static DataControlField GetColumn(this GridView grid, string id)
{
foreach (var column in grid.Columns)
if (column is IExtendedBoundField)
if (((IExtendedBoundField) column).Id == id)
return (DataControlField) column;
return null;
}
}
Related Content
- WebNet European Conference, Slides and Samples (11/06/2012)
- Css and JavaScript file minification (26/08/2015)
- Working on Dexter (26/08/2015)
- Tale of an ‘asp:Content control that do not correspond with asp:ContentPlaceHolder’ Master Page Error (26/08/2015)
- Missing .NET Performance Counters: how to solve it (10/07/2009)
- More related document (7)