Bind a Collection to a GridView

August 8, 2008 05:41 by wjchristenson2

Over the past few months I've had some requests to show how you can bind a custom object collection to a GridView.  When looking deeper into the collections, I noticed that the developers were working way to hard to create their collection class.   The collections were inheriting from System.Collections.Specialized.NameObjectCollectionBase and implementing IEnumerator, IEnumerable, & IUpdatable, etc to accomplish some simple tasks (ie: add, remove, for each loops, etc).  When implementing these interfaces, the developers were manually having to wire everything in.  On top of this, they were having problems binding to .NET controls.  Another quick point to make here is that the specialized collection does type casting at run time.

What I proposed was to inherit from System.Collections.Generic.List instead.  What this does is allow them to do their basic add, remove, sort, and manipulate their lists.  It also is strongly typed and can be accessed by index.  Generics provide better type safety and performance than non-generic collections (ie NameObjectCollectionBase mentioned above).

I'm going to create a simple vehicle collection and bind a GridView to it using the Generic.List.

Public Class Vehicle
    Private _Make As String = String.Empty
    Private _Model As String = String.Empty

    Public Property Make() As String
        Get
            Return _Make
        End Get
        Set(ByVal value As String)
            _Make = value
        End Set
    End Property

    Public Property Model() As String
        Get
            Return _Model
        End Get
        Set(ByVal value As String)
            _Model = value
        End Set
    End Property

    Public Sub New()

    End Sub

    Public Sub New(ByVal make As String, ByVal model As String)
        _Make = make
        _Model = model
    End Sub
End Class

Here is the vehicle class (object) that we'll reference in our collection.  Now for the collection.

Imports System.Collections.Generic

Public Class Vehicles
    Inherits List(Of Vehicle)

#Region "Constructors"
    Public Sub New()
        MyBase.New()
    End Sub

    Public Sub New(ByVal capacity As Integer)
        MyBase.New(capacity)
    End Sub

    Public Sub New(ByVal collection As IEnumerable(Of Vehicle))
        MyBase.New(collection)
    End Sub
#End Region

End Class

You'll notice how we inherit from System.Collections.Generic.List and cast the collection as a type of Vehicle.  It's as simple as that.  I added 3 constructors for your own reference.  Now all we have to do is add some data to the collection and bind a GridView to it.

Imports CollectionDataBinding.BLL

Partial Public Class _Default
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not Page.IsPostBack() Then
            GridView1_DataBind()
        End If
    End Sub

    Private Sub GridView1_DataBind()
        Dim myVehicles As Vehicles = New Vehicles()
        myVehicles.Add(New Vehicle("Ford", "Mustang"))
        myVehicles.Add(New Vehicle("Pontiac", "Grand AM"))

        Me.GridView1.DataSource = myVehicles
        Me.GridView1.DataBind()
    End Sub
End Class

On page load, I bind the GridView if it is not a postback.  I create a new instance of the Vehicles collection and add 2 vehicles to it.  I then simply set the data source of the GridView to the Vehicle collection and call DataBind().  Now, each public property will be mapped and shown in your GridView if you have AutoGenerateColumns="true" set.  If you don't do this, you'd approach the custom column mappings the same way as with a DataTable, DataView, etc (TemplateField, Eval expressions).

CollectionDataBinding_Soln.zip (89.23 kb)

>>>>> Edit 8/21/2008 <<<<<

I found another article that relates to this post.  It's a great reference as to the benefits of using generic collections.  The article lists the following reasons why you should use generic collections.

  1. Readability and simplicity of your code. Let’s take the case of getting the first string in a list of strings. With generics you would declare List<T> myList = new List<T>(); and then say string firstString = myList[0] just like working with arrays. This syntax is much more simple and readable than what you used to have to write which was ArrayList myList = new ArrayList(); and then string firstString = myList[0] as string;
  2. Performance. Every time you add a value type to a non-generic collection you have to box it to make it an object and every time you retrieve a value type from a non-generic collection you have to unbox it back from object. Even with reference type you still need to cast back to the correct type when retrieving items.
  3. Working against new smaller Framework SKUs. In Silverlight we decided to remove all the concrete non-generic collections completely from the codebase. This is mostly because the Silverlight core managed libraries is set to be the smallest useful set of classes. It’s also possible that other future small frameworks will not have the non-generic collections in store. If you ever plan to write code for those frameworks — you should convert it to use the generic collections.
  4. Better type-safe libraries. If you are developing libraries to be consumed by 3rd parties you should most definitely use generic collections when possible. This would allow consumer of your libraries to quickly figure out what’s expected to be stored in the collections instead of having to guess or figure out from documentation.
Bookmark and Share