How to pass external values with GridView HyperLinkField which are not part of your Gridview DataSource member ?

By | January 15, 2011

In this post, I am going to explain how you can pass some external values as parameters with the hyperlink field in GridView.

DataNavigationUrlField use only those fields as parameter which are the part of GridView DataSource. Now the problem comes when you want to pass some other variables as parameter which are not part of the DataSource. As shown in below image we are passing EmpID and ParentId as argument and this two field are the data member of GridView DataSource.

GridField

Now Say, You want pass ChildID for that particular record along with ParentID and EmpID and you want hyperlink url should be like “Default.aspx?EmpID=1&ParentID=P1&ChildID=C1”where ChildID is not part of datasource.

You can achieve this by writing code in code behind for the particular GridView. There is two events where you can overwrite the navigation url of that hyperlink field. You can use Gridview_RowDataBound or Gridview_PreRender for the same.

Let’s start with Gridview_RowDataBound . The RowDataBound event of GridView is raised when a data row is bound to data. So for each and every row RowDataBound event raised to bind with actual data from the data source. On the RowDataBound event you can check for the particular Cell control and can append the NavigateURL. Below is the code snippet for the same.

 /// <summary>
/// Handles the RowDataBound event of the grdStudent control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.Web.UI.WebControls.GridViewRowEventArgs"/> instance containing the event data.</param>
protected void grdStudent_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HyperLink hyperlink = (HyperLink)e.Row.Cells[0].Controls[0];
hyperlink.NavigateUrl += "&ChildID=" + this.ExternalValue;
}
}

And you can do the same thing in Gridview_PreRender event in similar way. As per the ASP.NET page life cycle, Pre_Render for control raised just before save view state and Render event. So this is the last event where you can customize your control before saving the viewstate data and rendering it. Below is the code snippet for the same.

/// <summary>
/// Handles the PreRender event of the grdStudent control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
protected void grdStudent_PreRender(object sender, EventArgs e)
{
foreach (GridViewRow row in grdStudent.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
HyperLink grdviewLink = (HyperLink)row.Cells[0].Controls[0];
grdviewLink.NavigateUrl += "&ChildID=" + this.externalValue;
}
}

}

If you want to know how it’s actually working, Just set breakpoint during databound, you will find NavigateURL for that hyperlink field has already been set with the value that you have passed as DataNavigationUrlField . And Inside RowDataBound or Pre_Render we are appending the the same NavigateURL with external parameter.

GridNavigation

GridUpdated

Below is the HTML snippet for the same HyperLinkField.

HyperlinkHTML

You can use NavigateURL properties for Hyperlinkfield to set url, but NavigateURL will set the same url for all the row. So if you want different url for each and every row you have to use DataNavigationUrlField or you need to override the NavigateURL during RowDataBound or Pre_Render. And If you set both the properties ( NavigateURL and DataNavigationUrlField ) the DataNavigationUrlField property takes precedence.


2 thoughts on “How to pass external values with GridView HyperLinkField which are not part of your Gridview DataSource member ?

  1. rtpHarry

    Personally I would follow a technique somewhat like this but I wouldn’t ever want code like (HyperLink)row.Cells[0].Controls[0] in my project. This is brittle and when you make a tweak to your GridView several months down the line you can easily miss this because the page will still compile, it just fails at run time.

    If you need to modify a HyperLinkField then you have moved beyond its simple purpose and I would convert it to a and then use (HyperLink)row.FindControl("MyNamedControl") instead. This protects you from the code breaking if you change the order of your columns.

Comments are closed.