interviews.dotnetthread.com

↑ Grab this Headline Animator

Sunday, February 15, 2009

Making GridView Rows or Individual Cells Clickable and Selectable.


Introduction:


In some scenarios we need to make GridView rows clickable and also in some cases we may need to make each cell of the GridView clickable like while developing reports.


We need to attach some event to each GridView row or each GridView cell to get the rowindex and cellindex (ColumnIndex) on which the user has clicked or double clicked.


This article shows you how to add attributes like click or double click GridView row or GridView individual cell and get the details of selected Row or Cell.


Description:


Making GridView with Selectable Rows:




  • First create a new Website application, attach any database or add connection string to the existing database in the web.config file.

  • Add gridview along with DataSource control (SqlDataSource control)on to the page. Configure DataSource control to get records from some table.

  • Assign DataSourceId of the GridView with the ID of the SqlDataSource control.

  • Add ButtonField to the GridView columns.


  • <asp:ButtonField CommandName="Select" Visible="false" />

  • As we know the GridView RowDatabound event is fired while binding each row to the GridView. Now we need to handle GridView OnRowDataBound event to modify each row as it is bound, where we can add attributes to each GridView row to handle Onclick or OnDouble click event by adding client script which is used by the SingleClick button for postback and assign it to the entire row.


  • protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
    // Get reference to button field in the gridview.
    LinkButton _singleClickButton = (LinkButton)e.Row.Cells[0].Controls[0];
    string _jsSingle = ClientScript.GetPostBackClientHyperlink(_singleClickButton, "Select$" + e.Row.RowIndex);
    e.Row.Style["cursor"] = "hand";
    e.Row.Attributes["onclick"] = _jsSingle;
    }
    }
    }

  • We can similarly add client script for double click as well.


  • protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
    // Get reference to button field in the gridview.
    LinkButton _singleClickButton = (LinkButton)e.Row.Cells[0].Controls[0];
    string _jsSingle = ClientScript.GetPostBackClientHyperlink(_singleClickButton, "Select$" + e.Row.RowIndex);
    e.Row.Style["cursor"] = "hand";
    e.Row.Attributes["ondblclick"] = _jsSingle;
    }
    }
    }

  • Now each row of the GridView is clickable and we can get the details of the user selected row in GridView OnSelectedIndexChanged event.

  • So we need to handle GridView’s OnSelectedIndexChanged event to get the selected row as below.


  • protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
    {
    GridViewRow selectedRow = GridView1.SelectedRow;
    lblSelectedRow.Text = GridView1.SelectedIndex.ToString();
    lblName.Text = selectedRow.Cells[2].Text;
    lblEmpId.Text = selectedRow.Cells[3].Text;
    }

  • To overcome Event Validation errors we need to handle Pages Render method. Otherwise we will get the Invalid postback or callback argument (Event validation is enabled using <pages enableEventValidation="true"/> 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.) error.

  • As we know that 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.

  • So add the following code on to the page to register each gridview row for event validation.


  • protected override void Render(HtmlTextWriter writer)
    {
    foreach (GridViewRow row in GridView1.Rows)
    {
    if (row.RowType == DataControlRowType.DataRow)
    {
    ClientScript.RegisterForEventValidation(((LinkButton)row.Cells[0].Controls[0]).UniqueID, "Select$" + row.RowIndex);
    }
    }
    base.Render(writer);
    }

  • Now everything is ready just run the page and u can find that each gridview row is selectable as show in below figure.



 


Making each GridView individual cells Clickable and Selectable:




  • First create a new Website application, attach any database or add connection string to the existing database in the web.config file.

  • Add gridview along with DataSource control (SqlDataSource control) on to the page. Configure DataSource control to get records from some table.

  • Assign DataSourceId of the GridView with the ID of the SqlDataSource control.

  • Add ButtonField with some Command Name say “ColumnClick” to the GridView columns.


  • <asp:ButtonField CommandName="ColumnClick" Visible="false" />

  • As we know the GridView RowDatabound event is fired while binding each row to the GridView. Now we need to handle GridView OnRowDataBound event to modify each cell in each GridView row as it is bound, where we can add attributes to each GridView cell to handle Onclick or OnDouble click event by adding client script which is used by the SingleClick button for postback and assign it to each cell.


  • protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
    LinkButton _singleClickButton = (LinkButton)e.Row.Cells[0].Controls[0];
    string _jsSingle = ClientScript.GetPostBackClientHyperlink(_singleClickButton, "");
    // Add events to each editable cell
    for (int columnIndex = 0; columnIndex < e.Row.Cells.Count; columnIndex++)
    {
    // Add the column index as the event argument parameter
    string js = _jsSingle.Insert(_jsSingle.Length - 2, columnIndex.ToString());
    // Add this javascript to the onclick Attribute of the cell
    e.Row.Cells[columnIndex].Attributes["onclick"] = js;
    // Add a cursor style to the cells
    e.Row.Cells[columnIndex].Attributes["style"] += "cursor:pointer;cursor:hand;";
    }
    }
    }
    }

  • We can similarly add client script for double click as well.

  • Now each row of the GridView is clickable and we can get the details of the user selected cell in GridView OnRowCommand event.

  • So we need to handle GridView’s OnRowCommand event to get the selected cell details as below. Within the RowCommand event, the command argument and the event argument are retrieved. This gives us the row and column index of the selected cell.


  • protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
    {
    if (e.CommandName.ToString() == "ColumnClick")
    {
    foreach (GridViewRow r in GridView1.Rows)
    {
    if (r.RowType == DataControlRowType.DataRow)
    {
    for (int columnIndex = 0; columnIndex < r.Cells.Count; columnIndex++)
    {
    r.Cells[columnIndex].Attributes["style"] += "background-color:White;";
    }
    }
    }
    int selectedRowIndex = Convert.ToInt32(e.CommandArgument.ToString());
    int selectedColumnIndex = Convert.ToInt32(Request.Form["__EVENTARGUMENT"].ToString());
    GridView1.Rows[selectedRowIndex].Cells[selectedColumnIndex].Attributes["style"] += "background-color:Red;";
    lblSelectedColumn.Text = selectedColumnIndex.ToString();
    lblSelectedRow.Text = selectedRowIndex.ToString();
    lblSelectedColumnTitle.Text = GridView1.Columns[selectedColumnIndex].HeaderText;
    lblSelectedColumnValue.Text = GridView1.Rows[selectedRowIndex].Cells[selectedColumnIndex].Text;
    }
    }

  • To overcome Event Validation errors we need to handle Pages Render method. Otherwise we will get the Invalid postback or callback argument (Event validation is enabled using <pages enableEventValidation="true"/> 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.) error.

  • As we know that 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.

  • So add the following code on to the page to register each gridview cell for event validation.


  • protected override void Render(HtmlTextWriter writer)
    {
    foreach (GridViewRow r in GridView1.Rows)
    {
    if (r.RowType == DataControlRowType.DataRow)
    {
    for (int columnIndex = 0; columnIndex < r.Cells.Count; columnIndex++)
    {
    Page.ClientScript.RegisterForEventValidation(r.UniqueID + "$ctl00", columnIndex.ToString());
    }
    }
    }
    base.Render(writer);
    }

  • Now everything is ready just run the page and u can find that each gridview cell is selectable as show in below figure.





Download the Sample Code here.




Submit this story to DotNetKicks

37 comments:

Anonymous said...

Very nice one....

Anonymous said...

A real good article. I will try it and will send you my feedback. Thanks.

Bikram.

Anonymous said...

That's the real thing.
Good work.

Anonymous said...

good job thanks

Anonymous said...

its nice

Vijeya Shobana said...

pretty useful article. good work author :)

Anonymous said...

Nice one!

Max said...

Thanks for this great tutorial, I have tried it in my own GridView, works like a charm! :)

Ashley said...

I am having some issues with this one...I am getting error message "Unable to cast object of type 'System.Web.UI.WebControls.Label' to type 'System.Web.UI.WebControls.LinkButton'." when running this code. Any suggestions?

Anil said...

Hi Ashley,

Make sure that you have added ButtonField as first column in GridView.

Anonymous said...

Hi,
How can i use this code to be able to select more than one cell at the same time?

Anonymous said...

Is there a VB.net version?

Anil said...

You can convert the code into VB.NET use tools like mentioned here to convert C# to VB.NET.

http://interviews.dotnetthread.com/2008/11/toolsc-to-vbnet-and-vbnet-to-c-online.html

Anonymous said...

thanks mama

Anonymous said...

To Good Article...It saved my life... Thanks man

Anonymous said...

Is it possible to do that with several dynamic gridviews ?

benwizzle11ty said...

are you able to put this into a function so it can be perfomed on a button click?

Anonymous said...

Very nicely done, this helped me out. A lot better done than a lot of other samples out there.

Anonymous said...

Very useful.Many Thanks
Regards
Feroz

Surinder said...

Very interesting....

Anonymous said...

That helped me a ton. Thanks for posting!!!

Anonymous said...

Thank you. Your article helped me tremendously. ~ Ken

khuram shehzad said...

Good Work

Palitha Nimala said...

Its Working ... Thank you very much.. and Good Luck!

Anonymous said...

Protected Sub gdEmp_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles gdEmp.RowCommand
If e.CommandName = "Select" Then
'Do select
Dim rowIndex As Integer = Integer.Parse(e.CommandArgument.ToString())
Dim lbl As Label = DirectCast(gdEmp.Rows(rowIndex).Cells(1).FindControl("Label1"), Label)
Dim connection = sqlcon()
Dim command As New SqlCommand("select * employee where empid=';", connection)
' For Each row As GridViewRow In gdEmp.Rows
Dim intId As Integer = gdEmp.SelectedIndex()
' Next
connection.Open()
command.ExecuteNonQuery()
connection.Close()
' ElseIf e.CommandName = "Deleterow" Then
'Do Delete
'Dim command As New SqlCommand("delete from employee;", connection)
End If
End Sub

Anonymous said...

any one help me in this how can i select the particular row or data of that row......

Anonymous said...

Im having a problem, i want to have MORE THAN ONE DATAGRID controls but the events above to be handled from the same handlers. i`ve made this change:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
GridView x = new GridView();
x = (GridView)sender;
foreach (GridViewRow r in x.Rows) ......

but when i select a cell in the second grid the cell in the first is deselected. Please help

Anonymous said...

Great Article! Helped me a lot!

Anonymous said...

I am working on this and i am a novice user or developer. I doubt is, your instructions say to ass a button field. Were do i add this button field in my page? some where around the grid??
Thank You

Anonymous said...

I am working on this and i am a novice user or developer. My doubt is, your instructions say to add a button field. Were do i add this button field in my page? some where around the grid??
Thank You

Anonymous said...

I am facing these errors. can any one please help me.
///
The name 'lblSelectedColumn' does not exist in the current context

The name 'lblSelectedRow' does not exist in the current context

The name 'lblSelectedColumnTitle' does not exist in the current context

The name 'lblSelectedColumnValue' does not exist in the current context
///

Thank you

Anil Kumar Reddy said...

Download the source code ...

Rufus McDoodle said...

Hi Anil,

Sorry to bother you but...
I've added your code to my project but the rows still aren't clickable.
I can watch the overridden 'render' function run, but the 'RowDataBound' code never runs. It's as if the event never fires.

I'm using an AccessDataSource instead of an SQLDataSource - Do you think this could make any difference to the events that get fired as the control is built for the page?

Thanks,
Paul.

ucaserkan said...

Makes perfect sense works good.You should face with a problem about linkbutton casting.you should check it from your designview section

Anonymous said...

hi is it possible to write click and double click events at the same time in rowdatabound.
i.e will click and double click events work simultaneously

Anonymous said...

Hi

Thanks for the article. Its very nice and helpful for me.

Rachha said...

wonderful article ever...
this is what i've been dreaming of since i started learning ASP.NET :P

Post a Comment

Post your comments/questions/feedback for this Article.

 

Latest Articles