How to implement full row selecting in GridView without select button?
Asked Answered
S

5

29

I'm implementing a feature that when the user press on any point in the row in a GridView the row will be selected instead of Select button.

enter image description here

To implement that, I'm using the following code:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // Set the hand mouse cursor for the selected row.
        e.Row.Attributes.Add("OnMouseOver", "this.style.cursor = 'hand';");

        // The seelctButton exists for ensuring the selection functionality
        // and bind it with the appropriate event hanlder.
        LinkButton selectButton = new LinkButton()
        {
            CommandName = "Select",
            Text = e.Row.Cells[0].Text
        };

        e.Row.Cells[0].Controls.Add(selectButton);
        e.Row.Attributes["OnClick"] =
             Page.ClientScript.GetPostBackClientHyperlink(selectButton, "");
    }
}

With the code above, there are the following problems:

  • This works fine only if I EnableEventValidation for the page is set to false.
  • The SelectedIndexChanged is only fired just in case the Grid.DataBind() is called in Page_Load for the page (in every postback).

Am I doing something wrong? Is there a better implementation?


Edit: When EnableEventValidation is set to true, the following error will appear:

Invalid postback or callback argument. Event validation is enabled using in configuration or <%@ Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.

Selima answered 6/6, 2011 at 10:13 Comment(0)
Y
46

You must add this on every postback and not only on databinding. Therefore you should use the RowCreated-Event of the GridView.

For example

(C#):

protected void GridView1_RowCreated(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow) {
        e.Row.Attributes["onmouseover"] = "this.style.cursor='pointer';this.style.textDecoration='underline';";
        e.Row.Attributes["onmouseout"] = "this.style.textDecoration='none';";
        e.Row.ToolTip = "Click to select row";
        e.Row.Attributes["onclick"] = this.Page.ClientScript.GetPostBackClientHyperlink(this.GridView1, "Select$" + e.Row.RowIndex);
    }
}

(VB.Net):

Private Sub GridView1_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowCreated
    If e.Row.RowType = DataControlRowType.DataRow Then
        e.Row.Attributes("onmouseover") = "this.style.cursor='pointer';this.style.textDecoration='underline';"
        e.Row.Attributes("onmouseout") = "this.style.textDecoration='none';"
        e.Row.ToolTip = "Click to select row"
        e.Row.Attributes("onclick") = Me.Page.ClientScript.GetPostBackClientHyperlink(Me.GridView1, "Select$" & e.Row.RowIndex)
    End If
End Sub
Yamashita answered 6/6, 2011 at 10:42 Comment(3)
this doesn't solve the problem of setting EnableEventValidation to false.Pruinose
@Homam: have you used my code and you are still getting the "invalid postback/callback argument"-error? I can't reproduce this error in my project, but there might be another reason for this. I have not the time now to investigate this further. You could use ClientScriptManager.RegisterForEventValidation to avoid it. Maybe this link helps.Yamashita
What language is that to describe the style? I've tried using CSS but that doesn't seem to work. For example its not background-color, its backgroundColor.Intestate
S
13

Instead of doing it on RowCreated, you could do it on Render(). That way you could use the overload of GetPostBackClientHyperlink with true on registerForEventValidation and avoid the "invalid postback/callback argument" error.

Something like this:

protected override void Render(HtmlTextWriter writer)
    {
      foreach (GridViewRow r in GridView1.Rows)
      {
        if (r.RowType == DataControlRowType.DataRow)
        {
          r.Attributes["onmouseover"] = "this.style.cursor='pointer';this.style.textDecoration='underline';";
          r.Attributes["onmouseout"] = "this.style.textDecoration='none';";
          r.ToolTip = "Click to select row";
          r.Attributes["onclick"] = this.Page.ClientScript.GetPostBackClientHyperlink(this.GridView1, "Select$" + r.RowIndex,true);

        }
      }

      base.Render(writer);
    }
Sukkah answered 27/3, 2013 at 17:16 Comment(1)
This also solved my problem. All the other posts on the Internet are telling you to disable EnableEventValidation which is opening your site up to injection attacks, this only one is the true answer.Maximomaximum
K
3
<style type="text/css">
    .hiddenColumn
    {
        display: none;
    }

    .rowGrid
    {
        cursor: pointer;
    }
</style>

<asp:GridView runat="server" ID="GridView1" AutoGenerateColumns="true" >
            <RowStyle CssClass="rowGrid" />
            <Columns>
                <asp:CommandField ButtonType="Button" ShowSelectButton="true" HeaderStyle-CssClass="hiddenColumn"
                    ItemStyle-CssClass="hiddenColumn" FooterStyle-CssClass="hiddenColumn" />
            </Columns>
        </asp:GridView>

<script type="text/javascript">
        $(function () {
            $("#<%= GridView1.ClientID %> tr.rowGrid")
            .live("click", function (event) {
                $(this).find("input[type='button'][value='Select']").click();
            });

            $("#<%= GridView1.ClientID %> input[type='button'][value='Select']")
                .live("click", function (event) {
                    event.stopPropagation();
                });

        });
    </script>
Kremlin answered 6/6, 2011 at 10:49 Comment(0)
F
0

Try this one add OnSelectedIndexChanged event in grid

   OnSelectedIndexChanged="Grid_SelectedIndexChanged"

and then on code behind

 protected void Grid_SelectedIndexChanged(object sender, EventArgs e)
{
    GridViewRow row = gvSummary.SelectedRow;
    //Int32 myvalue= Convert.ToInt32(row.Attributes["ColumnName"].ToString());
   } 

and set EnableViewState="false" but here u have to perform two more things that u have already done in your code means set EnableEventValidation to false and Grid Databinding on page Load..

Fraenum answered 6/6, 2011 at 10:56 Comment(0)
H
-2

Try using <asp:LinkButton> around your <tr> in ASPX code, set the LinkButton's CommandName='Select' And in item command event, process this command and set the style of a selected row!

Hoplite answered 6/6, 2011 at 10:31 Comment(4)
are you sure having a linikbutton between the td and the tr generates a valid fully compliant HTML ?Broeder
@Davide Piras: Standards compliant HTML was not mentioned in the question as a requirement! If that is a requirement, then don't accept the solution! I showed up some possibilities!Hoplite
I disagree, I did not vote you down and won't but even if not mentioned in original post, come on we are in Summer 2011 (almost), let's give cross browser and fully compliant answers only :) ;-)Broeder
@Davide Piras: I am not bothered about down votes! I fully agree with you about standards compliance! But, I just tried to help! Nothing more nothing less! I have faced a similar situation as @Homan, but then I had to get this working on production server at the earliest. So, then couldn't afford to look for standards compliance! ;-) Thought, this guy was also in a similar situation and would benefit from what I did at that time as a quick fix. Cheers! :-)Hoplite

© 2022 - 2024 — McMap. All rights reserved.