Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Select a Row in a Gridview with a Click on Row

0.00/5 (No votes)
9 Oct 2006 1  
This gridview enables the selection on a row click taking car to existing links in the row
Sample Image - screen.png

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 data 
  • DataDigest.Helper --> contains a recursive class helper which finds any type of controls in any control
  • DataDigest.WebControls --> contains the extender gridview class. Depends on the helper. This is what you need.

Using the Code

  1. 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;
      }
    }
    }
  2. 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");
              }
            }
          }
        }
      }
    }
  3. 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

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here