Welcome to AspAdvice Sign in | Join | Help

Developing a row-clickable GridView

Sometime ago, I demonstrated how to develop a row-clickable DataGrid control. Now, as we have a few holiday days here, I adopted the same to GridView in ASP.NET 2.0. Basic idea is the same, clicking the row (e.g entire row, not specific column) in the control causes a postback and throws RowClicked event. This can be used to customize selections a user can make with the control.

Code for the control

Imports Microsoft.VisualBasic
Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.WebControls

Namespace SampleControls


    Public Class MyGridView
        Inherits System.Web.UI.WebControls.GridView
       
#Region "Properties"

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

#Region "Event"


        Private Shared ReadOnly RowClickedEventKey As Object = New Object

        Public Custom Event RowClicked As EventHandler(Of GridViewRowClickedEventArgs) AddHandler(ByVal value As EventHandler(Of GridViewRowClickedEventArgs))
                Events.AddHandler(RowClickedEventKey, value)
            End AddHandler

            RemoveHandler(ByVal value As EventHandler(Of GridViewRowClickedEventArgs))
                Events.RemoveHandler(RowClickedEventKey, value)
            End RemoveHandler

            RaiseEvent(ByVal sender As Object, ByVal e As GridViewRowClickedEventArgs)
                Dim ev As EventHandler(Of GridViewRowClickedEventArgs) = TryCast(Events(RowClickedEventKey), EventHandler(Of GridViewRowClickedEventArgs))
                If ev IsNot Nothing Then
                    ev(sender, e)
                End If
            End RaiseEvent
        End Event

        Protected Overridable Sub OnRowClicked(ByVal e As GridViewRowClickedEventArgs)
            RaiseEvent RowClicked(Me, e)
        End Sub

#End Region

#Region "Postback handling"
        Protected Overrides Sub RaisePostBackEvent(ByVal eventArgument As String)
            If eventArgument.StartsWith("rc") Then
                Dim index As Integer = Int32.Parse(eventArgument.Substring(2))
                Dim args As New GridViewRowClickedEventArgs(Me.Rows(index))
                OnRowClicked(args)
            Else
                MyBase.RaisePostBackEvent(eventArgument)
            End If

        End Sub
#End Region

#Region "Adding the wiring from client-side to server-side, causing the posback when row is clicked"


        Protected Overrides Sub PrepareControlHierarchy()
            MyBase.PrepareControlHierarchy()

            If EnableRowClick Then
                Dim i As Integer
                For i = 0 To Rows.Count - 1
                    Dim argsData As String = "rc" & Rows(i).RowIndex.ToString()
                    Me.Rows(i).Attributes.Add("onclick", Page.ClientScript.GetPostBackEventReference(Me, argsData))
                Next
            End If

        End Sub

#End Region

    End Class

#Region "Custom event argument type"
    Public Class GridViewRowClickedEventArgs
        Inherits EventArgs

        Private _row As GridViewRow
        Public Sub New(ByVal row As GridViewRow)
            _row = row
        End Sub
        Public ReadOnly Property Row() As GridViewRow
            Get
                Return _row
            End Get
        End Property
    End Class
#End Region

End Namespace

Usage example

[aspx]

<%@ Register Namespace="SampleControls" TagPrefix="sc" %>
...
<sc:MyGridView ID="myGridView1" runat="server" AutoGenerateColumns=false EnableRowClick=true>
            <Columns>
                <asp:TemplateField HeaderText="Sample row header">
                    <ItemTemplate>
                    Sample row data
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns> 
 </sc:MyGridView>

[code-behind]

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not Page.IsPostBack Then
            Dim arr As New ArrayList()
            arr.Add(1)
            arr.Add(2)
            arr.Add(3)
            myGridView1.DataSource = arr
            myGridView1.DataBind()
        End If
    End Sub
   Protected Sub myGridView1_RowClicked(ByVal sender As Object, ByVal e As SampleControls.GridViewRowClickedEventArgs) 
Handles myGridView1.RowClicked

   Response.Write("Index of the clicked row was: " + e.Row.RowIndex.ToString())

End Sub

Edit:

In case you want the EnableRowClick to utilize control state feature (new in ASP.NET 2.0), instead of ViewState, you could have additional implementation (note the change in EnableRowClick property itself)

Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
            MyBase
.OnInit(e)
            Page.RegisterRequiresControlState(Me
)
        End Sub


       
Protected Overrides Function SaveControlState() As Object
           
Dim obj As Object = MyBase
.SaveControlState()

           
If _enablerowclick Then
                If obj IsNot Nothing Then
                    Return New
Pair(obj, _enablerowclick)
               
Else
                    Return
_enablerowclick
               
End If
            Else
'We do this because base call can return boolean itself
                Return New Pair(obj, False
)
           
End If
        End Function

        Protected Overrides Sub LoadControlState(ByVal savedState As
Object)
           
If savedState IsNot Nothing Then
                Dim p As Pair =
TryCast(savedState, Pair)
               
If p IsNot Nothing Then
                    MyBase
.LoadControlState(p.First)
                   
If p.Second IsNot Nothing Then
                        _enablerowclick =
CBool(p.Second)
                   
End If
                Else
                    If TypeOf savedState Is Boolean Then
                        _enablerowclick =
CBool(savedState)
                   
End If
                End If
            End If
        End Sub


       Private _enablerowclick As Boolean = False
        <DefaultValue(False
)> _
       
Public Property EnableRowClick() As
Boolean
           
Get

                Return
_enablerowclick
           
End Get
            Set(ByVal value As
Boolean)
                _enablerowclick
=
value
           
End
Set
       
End Property

Published Saturday, January 07, 2006 11:19 AM by joteke

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: Developing a row-clickable GridView

Thank you very much, I didn't saw the 1st example of DataGrid nor have had any need for clicking whole row yet, but now I am just getting ideas =)

found your blog just today, and to my surprise I assume you're a FINN (I am from Slovakia), exactly what I 'needed' more than this article hahaha =)

could I throw you an email (explaining), I would like to know some info about Finland ASP.NET job possibilities (e.g. I am learning finnish, 340 years to go to master it:) to get ASP.NET job w/o knowing finnish language...
Saturday, January 07, 2006 8:57 PM by Londyncan

# re: Developing a row-clickable GridView

You can use Contact link in "My links" to send me email.
Monday, January 09, 2006 6:16 AM by joteke

# Developing a row-clickable GridView

Joteke&#160;a post&#233; un&#160;exemple tr&#232;s simple et bien expliqu&#233; pour d&#233;velopper ajouter &#224; une gridView un &#233;v&#233;nement...
Monday, January 09, 2006 8:29 AM by Tonio's developper .NET Blog

# Developing a row-clickable GridView

Joteke&#160;a post&#233; un&#160;exemple tr&#232;s simple et bien expliqu&#233; pour d&#233;velopper ajouter &#224; une gridView un &#233;v&#233;nement...
Monday, January 09, 2006 9:08 AM by Tonio's developper .NET Blog

# re: Developing a row-clickable GridView

Great article !!!!
I've just done it in C# and it works well !
I have just added this (VB) :
Me.Rows(i).Style.Add("cursor", "hand")
in the PrepareControlHierarchy method, for indicating a link on mouse over the rows.
Sunday, January 15, 2006 1:45 PM by Laurent

# re: Developing a row-clickable GridView

Hi! This is really a question to Laurent. If you feel to share the c# code I'm very interested. Great article by the way but sadly not c#...

See ya!
Tuesday, January 24, 2006 8:48 PM by Arne (Sweden)

# re: Developing a row-clickable GridView

Has anybody converted to c# and would like to share?
Monday, March 06, 2006 1:01 AM by colinchee

# re: Developing a row-clickable GridView

people i need the code in c#, if some of you wanna to share, my email is reguapo@gmail.com
Monday, April 24, 2006 1:34 PM by reguapo

# re: Developing a row-clickable GridView

Great post, exactly what I was looking for... except in C#.
So I converted it to C#, removed the EnableRowClick property because I wouldn't use it if I didn't want to be able to click rows.
I added CSS class properties to the grid, to allow a different style applied to a row if hovered over.

using System;
using System.ComponentModel;
using System.Configuration;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace CustomGridView
{
 /// <summary>
 /// Summary description for ClickableGridView
 /// </summary>
 public class ClickableGridView : GridView
 {
   public string RowCssClass
   {
     get
     {
       string rowClass = (string)ViewState["rowClass"];
       if (!string.IsNullOrEmpty(rowClass))
         return rowClass;
       else
         return string.Empty;
     }
     set
     {
       ViewState["rowClass"] = value;
     }
   }

   public string HoverRowCssClass
   {
     get
     {
       string hoverRowClass = (string)ViewState["hoverRowClass"];
       if (!string.IsNullOrEmpty(hoverRowClass))
         return hoverRowClass;
       else
         return string.Empty;
     }
     set
     {
       ViewState["hoverRowClass"] = value;
     }
   }

   private static readonly object RowClickedEventKey = new object();

   public event GridViewRowClicked RowClicked;
   protected virtual void OnRowClicked(GridViewRowClickedEventArgs e)
   {
     if (RowClicked != null)
       RowClicked(this, e);
   }

   protected override void RaisePostBackEvent(string eventArgument)
   {
     if (eventArgument.StartsWith("rc"))
     {
       int index = Int32.Parse(eventArgument.Substring(2));
       GridViewRowClickedEventArgs args = new GridViewRowClickedEventArgs(Rows[index]);
       OnRowClicked(args);
     }
     else
       base.RaisePostBackEvent(eventArgument);
   }

   protected override void PrepareControlHierarchy()
   {
     base.PrepareControlHierarchy();

     for (int i = 0; i < Rows.Count; i++)
     {
       string argsData = "rc" + Rows[i].RowIndex.ToString();
       Rows[i].Attributes.Add("onclick", Page.ClientScript.GetPostBackEventReference(this, argsData));

       if (RowCssClass != string.Empty)
         Rows[i].Attributes.Add("onmouseout", "this.className='" + RowCssClass + "';");

       if (HoverRowCssClass != string.Empty)
         Rows[i].Attributes.Add("onmouseover", "this.className='" + HoverRowCssClass + "';");
     }
   }
 }

 public class GridViewRowClickedEventArgs : EventArgs
 {
   private GridViewRow _row;

   public GridViewRowClickedEventArgs(GridViewRow aRow)
     : base()
   {
     _row = aRow;
   }

   public GridViewRow Row
   {
     get
     { return _row; }
   }
 }

 public delegate void GridViewRowClicked(object sender, GridViewRowClickedEventArgs args);
}
Wednesday, May 17, 2006 4:21 PM by Paul R

# re: Developing a row-clickable GridView

I just converted it to C#, this is a great control. I also added a multiselectable checkbox column and enabled highlighting the mouseover row with a different CSS class.
I tried posting the code here a few hours ago but it hasn't shown up, maybe too long?
If you'd like the code, you can email me at pramsperger@cox.net
Wednesday, May 17, 2006 8:36 PM by Paul

# re: Developing a row-clickable GridView

Paul,

thank you for your contribution.

Comments are moderated due to the amount of spam I get. So it can take while to show up.

Teemu
Wednesday, May 17, 2006 11:21 PM by joteke

# &lt;Blog: Easyciel .NET /&gt; &raquo; Extending Gridview for ASP.NET 2.0

# re: Developing a row-clickable GridView

Hello Teemu:
Is it possible to do a CallBack instead of a postback when it comes to clicking the row?

Thanks.
Monday, June 19, 2006 6:57 AM by Bilal

# re: Developing a row-clickable GridView

When I click a row, I get a postback, but it doesn't seem to set that rows state as selected. I have selected row style set but does not apply when page reloads from postback.
I added a select column to the same grid and it applies the style.
Help?
Tuesday, June 20, 2006 5:16 PM by Pickedaname

# re: Developing a row-clickable GridView

Hello Pickdename:
You can add something as:

RaiseEvent(ByVal sender As Object, ByVal e As GridViewRowClickedEventArgs)
 Me.SelectedIndex = e.Row
               Dim ev As EventHandler(Of GridViewRowClickedEventArgs) = TryCast(Events(RowClickedEventKey), EventHandler(Of GridViewRowClickedEventArgs))
               If ev IsNot Nothing Then
                   ev(sender, e)
               End If
           End RaiseEvent

Hope this helps!
Friday, June 23, 2006 3:57 PM by Bilal

# C# version from Paul R: no Edit/Delete events?

Hi,

I'm using the C# code version from Paul R posted Wednesday, May 17, 2006 4:21 PM.

The RowClicked event is working fine but the control is not changing to edit mode or delete mode if I click on my command. I'm also not able to delete a row. My edit/delete commands looks like this:


<asp:TemplateField ShowHeader="False">                                    
                                   <HeaderStyle CssClass="GridHeader2" />
                                   <ItemStyle Width="45px" />
                                   <EditItemTemplate>
                                       <asp:LinkButton ID="cmdUpdate" runat="server" CssClass="CommandLink" CausesValidation="True" CommandName="Update">Update</asp:LinkButton><br /><br />
                                       <asp:LinkButton ID="cmdCancel" runat="server" CssClass="CommandLink" CausesValidation="False" CommandName="Cancel">Cancel</asp:LinkButton><br />
                                   </EditItemTemplate>                                    
                                   <ItemTemplate>
                                       <asp:LinkButton ID="cmdEdit" runat="server" CssClass="CommandLink" CausesValidation="False" CommandName="Edit">Edit</asp:LinkButton><br />
                                       <asp:LinkButton ID="cmdDelete" runat="server" CssClass="CommandLink" CausesValidation="False" CommandName="Delete" OnClientClick="return confirm('Delete this Job?');">Delete</asp:LinkButton><br />
                                       <asp:LinkButton ID="cmdHistory" runat="server" CssClass="CommandLink" CausesValidation="False" CommandName="History">History</asp:LinkButton>
                                   </ItemTemplate>
                               </asp:TemplateField>
Monday, July 31, 2006 10:40 AM by Dirk

# re: Developing a row-clickable GridView

Hi! I'm quite new with asp.net but I want to be able to click the rows. Got the vb version working fine but has problems with the c#. And I need the code in c# ofcourse :(
How would the EnableRowClick property look in c#.
Wednesday, August 02, 2006 7:28 AM by Frode

# re: Developing a row-clickable GridView

Hi!
I'm also using the C# version of this great control. There's only one problem that I'm trying to deal with: I've added this gridview to a DIV, which scrolls when needed. But whenever I click a row in the GridView, the scrollbar of the DIV goes back to the beginning of the grid. Does anyone know a way to force the row clicked to remain focused after the postback? Please?

Thanks!
(P.S: sorry for any English mistake)
Wednesday, August 09, 2006 8:49 AM by Lu

# re: Developing a row-clickable GridView

Frode,

[DefaultValue(false)]
   public bool EnableRowClick
   {
       get
       {
           bool ret = false;
           object obj = ViewState["EnableRowClick"];
           if (obj != null)
               ret = (bool)obj;
           return ret;
       }
       set
       {
           ViewState["EnableRowClick"]=value;
       }
   }
Wednesday, August 09, 2006 8:59 AM by Teemu

# re: Developing a row-clickable GridView

Lu,

Lu,

you need to store the scroll position with javascript. Set script into DIV's onscroll, BODY onclick etc, which you use to put scroll position into a server-side hidden input field. On postback, you read it back from the hidden input field and restorer DIV's scroll position.

The idea is explained in this forum post: http://forums.asp.net/thread/1084953.aspx
Wednesday, August 09, 2006 9:16 AM by joteke

# also &laquo; Perused

Sunday, May 27, 2007 9:46 PM by also « Perused

# http://aspadvice.com/blogs/joteke/archive/2006/01/07/14576.aspx

# re: Developing a row-clickable GridView

Awesome solution! Thanks!
Thursday, December 04, 2008 7:51 AM by Davez

# re: Developing a row-clickable GridView

Hi, I used C# Code posted by "Paul R", i have created Web Control Library then use this code and then i have used the DLL to my web application... now when i do some code in GridView1_RowClicked() event it gives me error: "The type name 'GridViewRowClicked' does not exist in the type 'sGrid.sGrid'" please note.... in My web Control Library i have namespace "sGrid" and public class name also "sGrid".. where i m doing wrong?? please reply. Thanks
Tuesday, December 30, 2008 8:57 AM by Shwetal

# Doubleclick event in DataView | keyongtech

Sunday, January 18, 2009 12:22 PM by Doubleclick event in DataView | keyongtech

# re: Developing a row-clickable GridView

Couldn't get this code to work, if someone could email me the complete vb code for this I'd much appreciate it. I keep on getting parser errors such as mygridview1 not found, cannot load type, etc... if someone could drop an email witht the vb files zipped to daniel.bhatoa@gmail.com I'd appreciate it. tx
Wednesday, September 02, 2009 6:03 AM by Dan

# re: Developing a row-clickable GridView

Very nice job !!! You saved my developper's life. Merci.
Tuesday, November 03, 2009 2:15 PM by Val&#233;rie MOUKDARATH

# re: Developing a row-clickable GridView

I'm running into a problem using paging with the row-clickable GridView (MyGridView). In a multi-page gridview, the following code runs fine on the first page of the grid: Protected Sub gvVoterList_RowClicked(ByVal sender As Object, ByVal e As Joteke.GridViewRowClickedEventArgs) Handles gvVoterList.RowClicked If e.Row.RowType = DataControlRowType.DataRow Then gvVoterList.SelectedIndex = e.Row.DataItemIndex Dim VoterID As String = gvVoterList.SelectedValue.ToString End If End Sub But if I move to any other page of the gridview, clicking on a row causes gvVoterList.SelectedValue to evaluate to Nothing, and I get a NullReferenceException: "Object reference not set to an instance of an object." Can anyone advise how to get around this problem?
Sunday, December 20, 2009 10:44 PM by Sheldon

# re: Developing a row-clickable GridView

I'm relatively new to C# and ASP.NET in general, and I must say that I got confused with all that code, even the one in C#. I believe that I'm in a lower-intermediate level right now, but can someone point me in the right direction on how to understand and utilize that code? Because I usually find it hard to use what I do not understand. Thanks.
Wednesday, January 13, 2010 3:27 AM by Sam

# 350sdl Chapter, 350sdl Dvd

Thursday, May 20, 2010 2:33 PM by 350sdl Chapter, 350sdl Dvd

# L200 Carmax, Headlight Ls1 2002 L200 2001 Saturn Sl1

Thursday, May 20, 2010 2:54 PM by L200 Carmax, Headlight Ls1 2002 L200 2001 Saturn Sl1

# Middletown Admission, Palma Discount Econo Lodge Convention Center

PingBack from http://350.mfbattle.com/

# Bmw 540i Engine Sale Drive, 540i Parts Used Salvage Yards Bmw 535i

# 2004 Cadillac Escalade Sale, Celebrity Car Hummer H2 Cadillac Escalade

# Cheap Saturn Lw1, Find Saturn Lw1 Pricing

Thursday, May 20, 2010 4:09 PM by Cheap Saturn Lw1, Find Saturn Lw1 Pricing

# Topaz Orthorhombic, Blue Topaz Briolette Chain

Thursday, May 20, 2010 5:15 PM by Topaz Orthorhombic, Blue Topaz Briolette Chain

# Buy 500e Mercedes Benz Clk, 500e Finatics

Thursday, May 20, 2010 5:58 PM by Buy 500e Mercedes Benz Clk, 500e Finatics

# Syclone Vehicle Back, C25 K2500 1500 Headlight Syclone Typhoon

# 1969 Dodge Coronet 4 Door Sedan, Coronet Radiator Cap

Thursday, May 20, 2010 8:31 PM by 1969 Dodge Coronet 4 Door Sedan, Coronet Radiator Cap

# Toyota Tundra Full Size Pickup Trucks, C35 C2500 Pickup Racing

# Sale Used Honda Crx Cars, Honda Crx Radiator Replacement Catalytic Converter

# Spalanie Dodge Viper Srt, Stealth Part Dodge Viper Twin Turbo

# 1966 Chevrolet Biscayne Added, Biscayne Headlight

Friday, May 21, 2010 7:03 AM by 1966 Chevrolet Biscayne Added, Biscayne Headlight

# Intrepid Travel Foundation Carbon Offset, Dodge Intrepid Part Seat Covers Chrysler

# C20 Pickup Fog Light Avalanche 2500, K30 Tacoma Avalanche 2500 Headlight Assembly

PingBack from http://380.mfbattle.com/

# re: Developing a row-clickable GridView

I have used your C# version and I noticed that the call back is delayed. I am not sure why there is such a delay on the item click and the other note is that the Row.DataItem is null.. If you have some thoughts on these could you post. I know that this thread is old and maybe there is something in 3.5 that needs to be looked at. But pretty much as is, the C# is working.
Monday, October 25, 2010 5:14 PM by RobbyeRob

Leave a Comment

(required) 
required 
(required) 
Enter the code you see below