Creating a Custom GridView Object

ASP.NET logo

An earlier post dealt with creating a GridView programmatically.  In some cases, this GridView might need to be used multiple times throughout a site, either using the same data, or perhaps a different set of data.  Several options exist when determining how to implement this.

The simplest, of course, would be simply to copy the code and then make changes in each copy as needed.  This clearly violates the DRY principle, and will only lead to heartache (and possibly carpal tunnel syndrome) in the long run.  As soon as the customer wants the look and feel of the GridView to change, you would have to change each instance where the code was copied.

The second, and slightly more desirable option, would be to refactor this code into a method that creates the GridView by calling the method.  While this is much preferable to having 20 verbatim copies of code in your site, it’s still not ideal.  This methodology contributes to spaghetti programming, and should be avoided when feasible.

The ideal method is to create an object that inherits from the GridView class, and then setting the attributes in the object.  Once the object is instantiated, any attributes that need to be added or overridden can be at runtime, prior to a databind event.

Here is an example of a class that inherits from GridView:

Public Class MyGridView
Inherits System.Web.UI.WebControls.GridView
Public Sub New(ByVal strID As String)
  ID = strID
  CssClass = "gridview"
  AutoGenerateColumns = False
  CellPadding = 4
  DataKeyNames = New String() {"ExampleID"}
  ForeColor = Drawing.ColorTranslator.FromHtml("#2a2723")
  GridLines = GridLines.None
  Width = Unit.Percentage(100)
  AllowSorting = True
  AllowPaging = False

  Dim strHeadBack As String = "#ffcb00"
  Dim strPagerBack As String = "#009ddb"
  Dim strForeColor As String = "#000000"

  HeaderStyle.BackColor = Drawing.ColorTranslator.FromHtml(strHeadBack)
  HeaderStyle.Font.Bold = True
  HeaderStyle.ForeColor = Drawing.ColorTranslator.FromHtml(strForeColor)

  RowStyle.BackColor = Drawing.ColorTranslator.FromHtml("#FFFBD6")
  RowStyle.ForeColor = Drawing.ColorTranslator.FromHtml("#2a2723")
  RowStyle.HorizontalAlign = HorizontalAlign.Center

  AlternatingRowStyle.BackColor = Drawing.Color.White

  BorderColor = Drawing.ColorTranslator.FromHtml("#d80073")
  BorderStyle = BorderStyle.Groove

  Dim ViewButton As New ButtonField
  ViewButton.HeaderText = "View"
  ViewButton.ButtonType = ButtonType.Button
  ViewButton.Text = "View"
  ViewButton.CommandName = "ViewExample"
  Columns.Add(ViewButton)

  Dim EditButton As New TemplateField
  EditButton.HeaderText = "Edit"
  EditButton.ItemTemplate = New MyButtonTemplate ' This is a user-defined class that creates this Button
  EditButton.Visible = bEditVisible
  Columns.Add(EditButton)

  Dim Voided As New CheckBoxField
  Voided.HeaderText = "Voided"
  Voided.DataField = "Voided"
  Voided.ReadOnly = True
  Voided.Visible = bVoidVisible
  Columns.Add(Voided)

  Dim ExampleDate As New TemplateField
  ExampleDate.HeaderText = "Date/Time"
  ExampleDate.SortExpression = "Date_and_Time"
  ExampleDate.ItemTemplate = New MyLabelTemplate ' This is a user-defined class that creates this Label
  ExampleDate.ItemStyle.Wrap = False
  Columns.Add(ExampleDate)

  Dim ShortColumn As New BoundField
  ShortColumn.ItemStyle.CssClass = "left"
  ShortColumn.HeaderText = "Short Column"
  ShortColumn.SortExpression = "Short_Column"
  ShortColumn.DataField = "Short_Column"
  ShortColumn.ItemStyle.Wrap = True
  ShortColumn.ItemStyle.Width = 150
  Columns.Add(ShortColumn)

  Dim LongColumn As New BoundField
  LongColumn.ItemStyle.CssClass = "left"
  LongColumn.HeaderText = "Long Column"
  LongColumn.SortExpression = "Long_Column"
  LongColumn.DataField = "Long_Column"
  LongColumn.ItemStyle.HorizontalAlign = HorizontalAlign.Left
  LongColumn.ItemStyle.Wrap = True
  LongColumn.ItemStyle.Width = 200
  Columns.Add(LongColumn)

  Dim CreatedBy As New BoundField
  CreatedBy.HeaderText = "Created By"
  CreatedBy.SortExpression = "CreatedBy"
  CreatedBy.DataField = "CreatedBy"
  Columns.Add(CreatedBy)
End Sub
End Class

To instantiate the object, simply declare the GridView as “MyGridView”, as below:

Private WithEvents gv1 As New MyGridView("gv1")

'...

gv1.DataSource = dvDataView  'A previously defined DataView

'...any other attributes to be added or overridden

' To remove a column use:

gv1.Columns.RemoveAt(x) ' where x is the index of the column

' Bind the data to the GridView

gv1.DataBind()

phPlaceHolder.Controls.Add(gv1)

And that’s it!  The custom GridView is like any other GridView; DataBind() can be called to rebind data, it can be hidden or made visible, etc.

Classics of Software Engineering

software engineering books

Even though I have been writing programs for most of my life, that does not mean that my programs have always been written well. Only following the standard prohibitions on spaghetti code and documenting well does not a good program make.

The best advice I ever got about writing programs was to read two books:

1. The Pragmatic Programmer, by Andy Hunt and Dave Thomas
2. Code Complete, 2nd Edition, by Steve McConnell

After applying the techniques from these books, your programs will be much easier to maintain, and much more efficient.

A third book that is also quite helpful is Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides (aka the Gang of Four).

These books are all available at Amazon.com in paper or Kindle format.

Guide for the Perplexed

Dave is disabling HAL in 2001: A Space Odyssey

With few exceptions, Web sites today are not built on a no-frills text editor using only static HTML code.  Most sites today use a minimum of four different technologies.  A relatively simple page will likely use HTML for static markup, inline (such as ASP or PHP) or code-behind (ASP.NET) dynamic code, CSS for consistent styles, and JavaScript for dialog box popups.  Given the multitude of technologies that are used to build even a single dynamic data-driven Web page, it’s impossible to know it all.

Though I’ve been writing programs since before most people had even heard of email, I still must frequently use Google (or my new favorite search engine, Duck Duck Go) to look up functions, formatted connection strings, .NET namespaces, SQL stored procedures, and the like.

Most of the time, if I can properly articulate what coding problem I’m trying to solve, a few minutes of searching will likely result in finding the code that will fix it.  In many cases, if I’m having a problem, it’s very likely that others have had it before, and that at least one of them posted the solution somewhere.

For those difficult times that I have had to either conjure up the code on my own or to use multiple other sources to build a solution that worked for me, I created this blog.  I hope to shed light on questions that were (at least to me) very perplexing, but for which I now have answers.

Welcome to my blog, and happy coding!

P.S.:

While I got my start on an Apple, and just recently bought my first Mac, the bulk of my professional work is using Windows-based technologies.  For my IDE, I generally use Visual Studio 2010.  Most of my applications are ASP.NET using VB, though I am doing all new development in C# where possible.   SQL Server 2008 is my DBMS of choice, though I do get to dabble in Oracle Database programming from time to time.  With any luck, I’ll get a chance to post some Cocoa / Objective-C code before the end of the year! 😀