Select a Row in a Gridview with a Click on Row






2.80/5 (10 votes)
This gridview enables the selection on a row click taking car to existing links in the row

Contents
Introduction
Maybe a lot of people know how it is easy in the .NET environment to extend a base class control to add some behaviors to it.
This is what I have done in this project. Maybe also, everybody has looked one day to add the ability to select a row in a gridview
with another way than adding the awful link "select" in one column of this control. The tip was simple, extend the base class gridview
and add a postback
event on each row when it is created.
But this last tip has one inconvenience of course, if we have some columns which contains some links like in the picture above, if we click on the link, this won't raise correctly. In any case, the postback
event of the row will be executed due to its hierarchical power. Then I had to find a little recursive solution that I want to propose to you.
Solution Assemblies
DataDigest.Business
-DataDigest.DataAccess
--> you don't need it, it's just quite an easy way to work with dataDataDigest.Helper
--> contains a recursive class helper which finds any type of controls in any controlDataDigest.WebControls
--> contains the extendergridview
class. Depends on the helper. This is what you need.
Using the Code
- The recurser class:
namespace DataDigest.Helper { public static class Recurser { /// <summary> /// this method check if a control or one of its children /// has the type of the types given by recursivity /// </summary> /// <param name="control">control to check</param> /// <param name="type">type to find</param> /// <returns>the first occurrence of control which has one of the given types /// </returns> public static Control ContainsControlType(Control control, params Type[] types) { // may be we could loop through the controls first and then the types // to gain some speed of process // but I wanted to ensure the same process for any control, // for the first one like its children //(cause the first one could have a given type) foreach (Type type in types) { if (control.GetType().Equals(type)) return control; else // begin recursivity foreach (Control ctrl in control.Controls) { Control tmpCtrl = ContainsControlType(ctrl, type); if (tmpCtrl != null) return tmpCtrl; } } // if no controls had the given type in the current control we return false return null; } /// <summary> /// Check if there is more than 0 links controls in a control or /// if this control is a link /// </summary> /// <param name="control">control to check in</param> /// <returns>true if there is any links</returns> public static bool ContainsLink(Control control) { bool ret = false; // search a link in the cell Control ctrl = ContainsControlType(control, typeof(HyperLink), typeof(LinkButton), typeof(DataBoundLiteralControl)); // if a control is returned, we have to check the case // of the literal which could contain no links if (ctrl != null) { if (ctrl.GetType().Equals(typeof(DataBoundLiteralControl))) { DataBoundLiteralControl dblc = (DataBoundLiteralControl)ctrl; // here I check if the text contains a href or onclick attribute // I assume that there this text should not be used to be displayed if (dblc.Text.Contains("href") || dblc.Text.Contains("onclick")) ret = true; } else ret = true; } return ret; } } }
- Extend the
gridview
:namespace DataDigest.WebControls { /// <summary> /// Behavior added to a row of a gridview : select on click event /// </summary> [DefaultProperty("SelectedValue")] [ToolboxData("<{0}:GridView runat="server"></{0}:GridView>")] public class GridView : System.Web.UI.WebControls.GridView { protected override void OnRowCreated(GridViewRowEventArgs e) { base.OnRowCreated(e); if (e.Row.RowType == DataControlRowType.DataRow) { foreach (TableCell cell in e.Row.Cells) { // if no link are present the cell, // we add the functionality to select the row on the cell with a click if (!Recurser.ContainsLink(cell)) { // here we add the command to postback when the user clicks // somewhere in the cell cell.Attributes.Add("onclick", Page.ClientScript.GetPostBackEventReference(this, "Select$" + e.Row.RowIndex.ToString())); cell.Style.Add(HtmlTextWriterStyle.Cursor, "pointer"); cell.Attributes.Add("title", "Select"); } } } } } }
- Add the reference of the assembly to your web.config then use the new user control ;)
Points of Interest
- Extending base classes
- How to get a
postback
reference
History
- 10th October, 2006: Initial post