Friday, April 15, 2011

Making an entire row clickable in a gridview

I have a gridview and I need to make an event fire when a row is clicked.

Is there an existing GridView event I need to bind to to make this happen?

From stackoverflow
  • There is no existing event to handle an entire row click. Your best bet is to have some javascript (maybe via ASP.NET Ajax) detect the click and fire the event yourself. Alternatively you would have to create a button or checkbox that the user selects.

  • You need to handle the "SelectedIndexChanged" event, you can then query the grid for the .SelectedRow. Alternativley use the "SelectedIndexChanging" event which sets "e.NewSelectedIndex"

    Cameron Saliba : But that events fires only when the GridView is being binded, no ? not when a user clicks a row
  • Check out this article by Teemu, in where he explains about clicking a row in Gridview and throw the RowClicked event.

    Here is a excerpt of the code:

    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
    
     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
    

    Btw, it's in VB not C# though.

  • Some javascript programming will be required in order to make this happen.

    Basically you are going to have to handle the click event for the row(is some browsers the row does not have a click event so you might have to handle the click event of the tds... time to invest in an ajax framework!)

    You will then from javascript have to fire a postback with the row index as a parameter. See encosia(a great site for ASP.Net - ajax implementations) on how to do that. Here is a link to an article along those lines

  • Here's something I prepared earlier:

    
    public class RowClickableGridView : GridView
        {
            public Style HoverRowStyle
            {
                get { return ViewState["HoverRowStyle"] as Style; }
                set { ViewState["HoverRowStyle"] = value; }
            }
    
            public bool EnableRowClickSelection
            {
                get { return ViewState["EnableRowClickSelection"] as bool? ?? true; }
                set { ViewState["EnableRowClickSelection"] = value; }
            }
    
            public string RowClickCommand
            {
                get { return ViewState["RowClickCommand"] as string ?? "Select"; }
                set { ViewState["RowClickCommand"] = value; }
            }
    
            public string RowToolTip
            {
                get
                {
                    if (!RowToolTipSet) return string.Format("Click to {0} row", RowClickCommand.ToLowerInvariant());
                    return ViewState["RowToolTip"] as string;
                }
                set
                {
                    ViewState["RowToolTip"] = value;
                    RowToolTipSet = true;
                }
            }
    
            private bool RowToolTipSet
            {
                get { return ViewState["RowToolTipSet"] as bool? ?? false; }
                set { ViewState["RowToolTipSet"] = value; }
            }
    
            protected override void OnPreRender(EventArgs e)
            {
                base.OnPreRender(e);
                foreach (GridViewRow row in Rows)
                {
                    if (row.RowType != DataControlRowType.DataRow) continue;
    
                    if (EnableRowClickSelection && row.RowIndex != SelectedIndex && row.RowIndex != EditIndex)
                    {
                        if (string.IsNullOrEmpty(row.ToolTip)) row.ToolTip = RowToolTip;
                        row.Style[HtmlTextWriterStyle.Cursor] = "pointer";
    
                        PostBackOptions postBackOptions = new PostBackOptions(this,
                                                                              string.Format("{0}${1}",
                                                                                            RowClickCommand,
                                                                                            row.RowIndex));
                        postBackOptions.PerformValidation = true;
                        row.Attributes["onclick"] = Page.ClientScript.GetPostBackEventReference(postBackOptions);
    
    
                        foreach (TableCell cell in row.Cells)
                        {
                            foreach (Control control in cell.Controls)
                            {
                                const string clientClick = "event.cancelBubble = true;{0}";
                                WebControl webControl = control as WebControl;
                                if (webControl == null) continue;
                                webControl.Style[HtmlTextWriterStyle.Cursor] = "Auto";
                                Button button = webControl as Button;
                                if (button != null)
                                {
                                    button.OnClientClick = string.Format(clientClick, button.OnClientClick);
                                    continue;
                                }
                                ImageButton imageButton = webControl as ImageButton;
                                if (imageButton != null)
                                {
                                    imageButton.OnClientClick = string.Format(clientClick, imageButton.OnClientClick);
                                    continue;
                                }
                                LinkButton linkButton = webControl as LinkButton;
                                if (linkButton != null)
                                {
                                    linkButton.OnClientClick = string.Format(clientClick, linkButton.OnClientClick);
                                    continue;
                                }
                                webControl.Attributes["onclick"] = string.Format(clientClick, string.Empty);
                            }
                        }
                    }
    
                    if (HoverRowStyle == null) continue;
                    if (row.RowIndex != SelectedIndex && row.RowIndex != EditIndex)
                    {
                        row.Attributes["onmouseover"] = string.Format("this.className='{0}';", HoverRowStyle.CssClass);
                        row.Attributes["onmouseout"] = string.Format("this.className='{0}';",
                                                                     row.RowIndex%2 == 0
                                                                         ? RowStyle.CssClass
                                                                         : AlternatingRowStyle.CssClass);
                    }
                    else
                    {
                        row.Attributes.Remove("onmouseover");
                        row.Attributes.Remove("onmouseout");
                    }
                }
            }
    
            protected override void Render(HtmlTextWriter writer)
            {
                base.Render(writer);
                foreach (GridViewRow row in Rows)
                {
                    if (row.RowType == DataControlRowType.DataRow)
                    {
                        Page.ClientScript.RegisterForEventValidation(row.ClientID);
                    }
                }
            }
        }
    
    

    You then hook into the standard row command events...

    David M : Just tried this - works nicely!
    Eddie : +1 Worked for me too! Thanks.

0 comments:

Post a Comment