Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Extended ASP.NET GridView with cell click events

4.71/5 (7 votes)
21 Jan 2010CPOL2 min read 79K   2K  
An extended ASP.NET Gridview control with cell click events.

Download Code and Demo Solution  - 184.4 KB

Introduction

The ASP.NET GridView is an excellent control and is widely used, but still lacks some features. This article demonstrates extending the GridView to add cell click event handling by inheriting from the base GridView class, overriding and changing some of the properties and behaviour.

Background

After doing some research, there seems to be not a lot of resources with regards to cell click event handling in the ASP.NET GridView. I have found one or two articles where you have to add some JavaScript functions to the RowDataBound() event of the GridView. I wanted an out-of-the-box gridview with this functionality. Finally, I came across a blog post by Jonni Teemu Keiski called Developing a row-clickable GridView, and started from there by applying the same principle to the cells of the GridView.

Using the code

Adding a designer property: Enable cell-click

Since we opt to have a generic control, we add a property that the programmer can set to enable postback events when a cell is clicked.

VB
<DefaultValue(False)> _
Public Property EnableCellClick() As Boolean
    Get
        Dim ret As Boolean = False
        Dim obj As Object = ViewState("EnableCellClick")
        If obj IsNot Nothing Then
            ret = CBool(obj)
        End If
        Return ret
    End Get
    Set(ByVal value As Boolean)
        ViewState("EnableCellClick") = value
    End Set
End Property

Adding a class for the arguments of the cell-click event

In order to return the properties of the cell that was clicked, we create a new custom event argument that inherits the base event argument class. We will return the custom event argument in the custom event handler CellClicked() that we'll create in the next section.

VB
Public Class GridViewCellClickedEventArgs _
        Inherits EventArgs
    Private mobjCell As TableCell
    Private mobjRow As GridViewRow
    Private mintColumnIndex As Integer
    Public Sub New(ByVal Cell As TableCell, _
                   ByVal row As GridViewRow, _
                   ByVal ColumnIndex As Integer)
        mobjCell = Cell
        mobjRow = row
        mintColumnIndex = ColumnIndex
    End Sub
    Public ReadOnly Property Cell() As TableCell
        Get
            Return mobjCell
        End Get
    End Property
    Public ReadOnly Property Row() As GridViewRow
        Get
            Return mobjRow
        End Get
    End Property
    Public ReadOnly Property ColumnIndex() As Integer
        Get
            Return mintColumnIndex
        End Get
    End Property
End Class

Creating an event for the cell click

In the next section, we will add a custom event which will return our custom event argument created previously for the programmer to use:

VB
Protected Sub XGridView1_CellClicked(ByVal sender As Object, _
           ByVal e As CustomControls.GridViewCellClickedEventArgs) _
           Handles XGridView1.CellClicked
    'Do Something
     Response.Write("Contents of cell clicked: " & e.Cell.Text)
     Response.Write("Zero based column index of clicked cell: " & e.ColumnIndex)
End Sub

Adding the custom event

The custom event contains AddHandler, a RemoveHandler which simply tells the call to attach or remove the given event handler from the cell's click event.

Lastly, we'll use a RaiseEvent implementation to raise the event as in the previous section (e.g., XGridView1_CellClicked()).

VB
Public Custom Event CellClicked As EventHandler(Of GridViewCellClickedEventArgs)
  AddHandler(ByVal value As EventHandler(Of GridViewCellClickedEventArgs))
      Events.AddHandler(CellClickedEventKey, value)
  End AddHandler
  RemoveHandler(ByVal value As EventHandler(Of GridViewCellClickedEventArgs))
      Events.RemoveHandler(CellClickedEventKey, value)
  End RemoveHandler
  RaiseEvent(ByVal sender As Object, ByVal e As GridViewCellClickedEventArgs)
      Dim ev As EventHandler(Of GridViewCellClickedEventArgs) = _
      TryCast(Events(CellClickedEventKey), _ 
       EventHandler(Of GridViewCellClickedEventArgs))
      If ev IsNot Nothing Then
         ev(sender, e)
      End If
  End RaiseEvent
End Event

Protected Overridable Sub OnCellClicked(ByVal e As GridViewCellClickedEventArgs)
  RaiseEvent CellClicked(Me, e)
End Sub

Adding the attributes of the base control (GridView) to the child controls (TableCell)

The next step is to apply the click event and event arguments to the child control which is the TableCell of the GridView. This is done by overriding the PrepareControlHierarchy() method of the base class.

VB
For i As Integer = 0 To Rows.Count - 1
     For j As Integer = 0 To Rows(i).Cells.Count - 1
         'Row Index                                'Column Index              
         Dim argsData As String = "cc" & ";" & Rows(i).RowIndex.ToString & _
           ";" &   j.ToString
         Me.Rows(i).Cells(j).Attributes.Add("onclick", _ 
         Page.ClientScript.GetPostBackEventReference(Me, argsData))
     Next
Next

Handling the postback

Finally, we override the RaisePostBackEvent() event. In this method, the GridView's events are raised when a postback happens on the server. We will override the method to determine from the EventArgument whether the event was caused by clicking a cell. From here, we use the event data to create a new instance of GridViewCellClickedEventArgs and pass it to the OnCellClicked() method.

VB
Protected Overrides Sub RaisePostBackEvent(ByVal eventArgument As String)
    If eventArgument.StartsWith("cc") Then      'Cell click
       Dim lcolIndices() As String = eventArgument.Split(";")
       Dim lintRowIndex As Integer = lcolIndices(1).ToString()
       Dim lintColumnIndex As Integer = lcolIndices(2).ToString()
       Dim args As New GridViewCellClickedEventArgs(Me.Rows(lintRowIndex). _
           Cells(lintColumnIndex), Me.Rows(lintRowIndex), lintColumnIndex)
       OnCellClicked(args)
     Else
        MyBase.RaisePostBackEvent(eventArgument)
     End If
End Sub

Adding the control to a webpage

ASP.NET
<%@ Register Assembly="XGridView" 
   Namespace="CustomControls" TagPrefix="cc1" %>
<cc1:XGridView ID='XGridView' runat="server" EnableCellClick="True" 
        DataSourceID="XmlDataSource1" >
</cc1:XGridView>

Note that we have enabled the cell click in the markup, but it can also be set in the property designer in the IDE.

Adding some code to the CellClicked() event

VB
Protected Sub XGridView_CellClicked(ByVal sender As Object, _
         ByVal e As CustomControls.GridViewCellClickedEventArgs) _
         Handles XGridView.CellClicked
   lblResult.Text = "Index of the cell clicked was:  " & e.ColumnIndex.ToString  
   lblResult0.Text = "Value of cell clicked:  " & e.Cell.Text.ToString 
   lblResult1.Text = "Index of the row clicked was:  " & e.Row.RowIndex
End Sub

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)