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

Code Project - Frequently Asked Questions Series 1: The ASP.Net GridView

0.00/5 (No votes)
14 Sep 2011 1  
Frequently Asked Questions on ASP.Net GridView at Code Project Question Answer Forum

Table of Contents

Introduction

While answering questions on the Question and Answer Forums[^], we noticed a certain pattern to the questions being asked very frequently. Rather than trying to answer each question on an ad-hoc and individual basis, we decided to club together a set of commonly asked questions into an article. Everytime we notice a similar pattern-based question being asked, we will now provide a link to this article, instead of providing different answers for each question. This will help us to answer better and people can have a look at other alternative solutions as well.

Let's start with ASP.NET GridView, which is an extremely flexible data control in ASP.NET. It was observed that a number of questions pertaining to the ASP.Net GridView are asked daily. There will be a question on exporting the GridView to Excel almost daily. Questions on GridView Template field, Hiding specific values from a Cell, Changes Cell Values at run time are very common as well.

Many other such patterns can be found if some time is spent in the Q&A forums.

We hope to keep this article updated by continuously adding more commonly asked questions to it.  

Is it Possible to have AutoGenerateColumns set to true and define Columns in "Columns" Section?  

Yes. You can. Though this is not a very common situation when you are enabling the AutoGenerateColumns="true" and define custom columns. GridView creates a columns for each field when AutoGenerateColumns=true. We set AutoGenerateColumns=false, when we need few specific fields from the data source and define the cutom columns section with different types of columns.

So what will happen, if we set AutoGenerateColumns to true and add "Columns" section to define columns? GridView will generated columns for each and every field, but before these auto generated columns, it will add the columns that you define explicitly.

How do we bind GridView Data Source with explicit columns?

GridView allows several types of columns to bind data that can be define explicitly. One of the most common column type is "BoundField". Apart from bound field, GridView supports different types of Columns which includes ButtonField, ImageField, HyperLinkField, TemplateField etc. Let's have a quick look on how we can use BoundField to define gridview columns explicitly.

BoundField has a properties called "DataField". The DataField needs to associate with any of the data objects of the GridView DataSource.

This type column binding provides you enough opportunity to customize the columns and headers.

Formatting Column Values in GridView

Another frequently asked question is how do we format a cell value? GridView BoundField columns provides a property "DataFormatString" which you can use to format data. DataFormatString take similar arguments like String.Format, where it has one placeholder and another format indicator.  

Here is a quick example of Date Formatting

This is also very useful when we need formatting for a Currency field. You can find list of all formatting string over here.

How to access Values of Template Field in GridView?

GridView TemplateField allows us to specify custom controls, multiple fields and Html using a custom template. TemplateField allows us to define a completely customized template for GridView Column. We can bind the data with in template control using binding expression. ASP.NET provides number of ways to take control over the template control.

Let's consider you have following design in a gridview  

You now want to access the value of this label from code behind, where you want to update the text or you want to do some additional operation based on the value of label or other value. In the code snippet below we have shown that if the name is start with "A" it won't be displayed.

   protected void myGrid_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                Customer cust = e.Row.DataItem as Customer;
                if (!cust.ShowURL)
                {
                    Label lableName = e.Row.FindControl("Label1") as Label;
                    if (lableName.Text.StartsWith("A"))
                    {
                        lableName.Visible = false;
                    }
                }
            }
        }


So, for any situation, if you want to access the controls that are inside Template Fields, first check if the row is a "DataRow", then your GridViewRow.FindControl method to get the control. Once you have the control of the same type you can do all additional operations.

Dynamically set control visibility inside ItemTemplate’s of GridView

If you want to hide any fields or control based on some conditional value, you can either do it from code behind or your can take help of a bind expression.

If you are following the approach of code behind, first of all, if need to find the control value during RowDataBound of the Gridview. Once your have control, you can set the visibility of the control based on the condition that you want to apply.

The example below shows hiding a linkbutton based on some condition.

  protected void myGrid_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                Customer cust = e.Row.DataItem as Customer;
                if (!cust.ShowURL)
                {
                    LinkButton lnkWebURL = e.Row.FindControl("lnk") as LinkButton;
                    if (lnkWebURL != null)
                    {
                        lnkWebURL.Visible = false;
                    }
                }
            }
        }
Well, you can achieve the same thing in a smart way by just using Binding Expression. We can use Conditional Expression with in GridView Bind expression. So whatever you wrote in code behind can be replaced by just

This will first evaluate the value of "ShowURL" and then set the Visible property of GridView.

This question was recently asked in Q&A Forums, I answered and put a detailed blog post with an explanation at Dynamically set control visibility inside ItemTemplate’s of GridView using Bind Expression.

Displaying Custom Messages / Images with NULL Value in ASP.NET GridView

When we bind some data source with a GridView which contains some fields with NULL value, ASP.NET renders them as blank. But most of the time, we need to show a custom messages or images instated of null value. You can take help of RowDataBound method for this and override the null value. Instead of doing that, its better to make use of "NullDisplayText" properties to replace the null value.

This will replace all the null values with plain text "No Data"

Once we mentioned NullDisplayText=”No Data”, every field for that Bound Field which contains a NULL value will be replace by “No Data” . 

We can even customize the Text with HTML Formatting as shown below

The output will be as below

Original Source : Displaying Custom Messages / Images with NULL Value in ASP.NET GridView

How to Display “Yes” or “No” Instead of Checkbox while binding Boolean value with GridView?

If you are binding some data source in grid view which is having a field type of Boolean, then the Grid View renders it as a “Checkbox” . But sometime we may required to display either Yes/ No or “1/0” instead of Checked/ Unchecked Text Box.

You can simple update the cell value on RowDataBind and change the default value as required.

protected void GridView2_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Student s = (Student)e.Row.DataItem;
if (s.Status == true)
{
e.Row.Cells[2].Text = "1";
}
else
{
e.Row.Cells[2].Text = "0";
}
}
}

You can find the complete tips over here How to Display “Yes” or “No” Instead of Checkbox while binding Boolean value with GridView?

How to pass multiple values using GridView HyperLinkField?

While working with GridView in ASP.NET, most of the times we use a HyperlinkField column to navigate from one page to different page with some value as argument. In this blog post, I have explained how can we pass multiple parameter with HyperLinkField in GridView. To implement this feature you need to know about DataNavigationUrlField and DataNavigateUrlFormatString properties of HyperLinkField. Let’s assume that you have a gridview as given below and you have already bind the Datasource from code behind.
 <asp:gridview id="GrdEmp">

<columns  runat="server" autogeneratecolumns="False" cellpadding="4">

<asp:boundfield datafield="ID" headertext="ID">

<asp:boundfield datafield="Name" headertext="Name">

<asp:boundfield datafield="ParentID" headertext="Base ID">


Let’s first consider the case of passing single parameter. The first thing that you need to do, is, to add a GridView “HyperLinkField “ column. After that you need to set the DataNavigationUrlField and DataNavigateUrlFormatString properties for the same . In DataNavigationUrlField you have to mention the name of the DataField which you want to bind as querystring. In DataNavigateUrlFormatString you have to give the formatted URL String for the Navigation. The concept is same here as like FormatString the only difference is the data is coming from DataNavigationUrlField.  

<asp:hyperlinkfield text="Details" datanavigateurlfields="ID" datanavigateurlformatstring="/Details.aspx?EmpId={0}">


In the above example, I have passed an ID as a DataNavingationUrlField. So asthe Gridview Binds, for each row corresponding ID will be bind as url string with Employee ID. The code snippet for the for the HTML View is right below.
<a href="http://www.codeproject.com/Default.aspx?EmpID=123">Details</a>
To add multiple parameters you need to specify multiple DataField with comma(,) separated with in DataNavigateURLFields and also need to provide the DataNavigateURLFormatString with proper number of argument.
asp:hyperlinkfield datanavigateurlformatstring="/Details.aspx?EmpId={0}&ParentID={1}" datanavigateurlfields="ID,ParentID" text="Details">

This is the HTML output for multiple parameter HyperLinkField.

<a href="http://www.codeproject.com/Default.aspx?EmpID=123&ParentID=765">Details</a>  
So, to summarize the post, you can use Comma separated DataNavigateURLFields to pass multiple DataField as an parameter with HyperlinkField in GridView. Also you need to use proper formatted URL with DataaNavigateURLFormatString.

Original Source : How to pass multiple values using GridView HyperLinkField ?

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

DataNavigationUrlField uses only those fields as parameter which are part of GridView DataSource. Now the problem comes when you want to pass some other variables as parameters which are not part of the DataSource. As shown in the image below, we are passing EmpID and ParentId as arguments and these two field are the data members of GridView DataSource

GridField

Now say, you want to pass ChildID for that particular record along with ParentID and EmpID and you want that the 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 are 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 is 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 a similar way. As per the ASP.NET page life cycle, Pre_Render for control is raised just before save view state and Render event. 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 a 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 same NavigateURL with an 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 rows. So if you want a 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.

Export a GridView To Excel

Exporting a GridView to Microsoft Excel is one of the most common questions asked in the forum.

The approach to this is fairly simple. The GridView can be copied row by row into an html table. This table can be written to an html stream and there, we have the excel.

Let us look at some code. The UI is fairly simple with a GridView containing some data and an export to excel button. This is what the UI would look like.

UI_VIew.JPG

The UI code is just two lines and for completion sakes is being shown here.

<asp:gridview runat="server" autogeneratecolumns="true" height="66px" width="543px" style="z-index: 118" id="GridView1">
 <asp:button onclick="Button1_Click" text="Export to Excel" runat="server" id="Button1">

The main code is written in the button click event. We will use the HttpContext's Response object. An excel header is added to the Response object (with the corresponding MIME type).

A StringWriter object is created first. A HtmlTextWriter object is created from this StringWriter. An html Table is then created and the GridView is copied row by row into this table. This table is then rendered into the HtmlTextWriter object. The StringWriter object is then written into the Response and the browser is able to parse the response as an Excel file (provided it recognises the Excel MIME type).

Here is the code

protected void Button1_Click(object sender, EventArgs e)
{
    HttpContext.Current.Response.Clear();
    HttpContext.Current.Response.AddHeader("content-disposition",
        string.Format("attachment;filename={0}.xls", "Exported"));
    HttpContext.Current.Response.Charset = "";
    HttpContext.Current.Response.ContentType = "application/ms-excel";

    using (StringWriter sw = new StringWriter())
    {
        using (HtmlTextWriter htw = new HtmlTextWriter(sw))
        {
            //  Create a table to contain the grid
            Table table = new Table();

            foreach (GridViewRow row in GridView1.Rows)
            {
                table.Rows.Add(row);
            }

            //  render the table into the htmlwriter
            table.RenderControl(htw);

            //  render the htmlwriter into the response
            HttpContext.Current.Response.Write(sw.ToString());
            HttpContext.Current.Response.End();
        }
    }
}

http://mattberseth.com/blog/2007/04/export_gridview_to_excel_1.html [^] is a good link on exporting a GridView to Excel, and this is what was referred to while preparing this tip.

Importing an Excel to a GridView

A common question (though not as common as export to Excel) is importing an Excel file into a GridView. For this example, we will use a FileUpload control to choose an excel from a particular drive. Note that FileUpload does not return the full file path to the server due to security reasons. The UI and its code look like this.

ImportGridView.jpg

An import button is provided to do the actual import to the GridView. Binding is used to allow the GridView to bind to imported data. The code behind on the Import button's Click event is below.

protected void Import_Click(object sender, EventArgs e)
{
    DataSet ds = new DataSet();

    String strConn = @"Provider = Microsoft.ACE.OLEDB.12.0;" + @"Data Source=C:\" + MyFile.FileName + @";Extended Properties='Excel 12.0;HDR=Yes;'";
    OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", strConn);

    da.Fill(ds);
    GridView1.DataSource = ds.Tables[0].DefaultView;
    GridView1.DataBind();
}

Some lines of the above code require an explanation. In this example, the Jet engine is used to read an Excel file as the database. The connection string's provider points to the OLEDB.12.0 version (rather than the 4.0 one) because Excel 2007 is being used. Thus the Extended Properties section is different as well. HDR is nothing but an attribute that suggests that the first row in the Excel is to be used as a header (when set to YES). The entire connection string would be different when connecting to Excel 2003 or older. A DataSet is filled using a DataAdapter and the first table is assigned to the GridView. That's all there is to it.

Another aproach to implement 'Import to Excel' would have been to use Excel Interop. This approach is not discussed here.

Dropdown in a GridView

Adding a Dropdown in a GridView is a fairly common question as well.

Lets first have a look at the aspx code. In order to define a dropdown, we will need to add ItemTemplates to the code. The first two columns, Name and Age, will be simple DataBinders. The third ItemTemplate will contain a DropDownList. Remember, AutoGenerateColumns has been set to false. Fairly simple till here.

<columns>
<asp:templatefield headertext="Name">
    <itemtemplate>
        <%# DataBinder.Eval(Container.DataItem, "Name")>
    </itemtemplate>
</asp:templatefield>
<asp:templatefield headertext="Age">
    <itemtemplate>
        <%# DataBinder.Eval(Container.DataItem, "Age")>
    </itemtemplate>
</asp:templatefield>
<asp:templatefield sortexpression="Occupation" headertext="Occupation">
    <itemtemplate>
         <asp:dropdownlist id="DropDownList1" runat="server">
    </itemtemplate>
</asp:templatefield>
</columns>

This is the UI the user sees on their screen.

Image_2.jpg

The GridView is populated using a DataTable. This is fairly easy as well.

DataTable dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("Age");
dt.Columns.Add("Occupation");

DataRow dr = dt.NewRow();
dr["Name"] = "Chris Harris";
dr["Age"] = "40";
dr["Occupation"] = "Doctor";
dt.Rows.Add(dr);

dr = dt.NewRow();
dr["Name"] = "Sean Williams";
dr["Age"] = "39";
dr["Occupation"] = "Plumber";
dt.Rows.Add(dr);

dr = dt.NewRow();
dr["Name"] = "Paul Newcombe";
dr["Age"] = "38";
dr["Occupation"] = "Lecturer";
dt.Rows.Add(dr);

GridView1.DataSource = dt;
GridView1.DataBind();

Now comes the slightly tricky part. In order to populate the GridView's DropDownList, we need to run a loop through every row and find the DropDownList within that row. This could be avoided if we had a static DataSource. Here though, we are using a DataSource generated at rutime, we find the DropDownList and then bind it to the same dynamic DataSource's Occupation column.

            
foreach (GridViewRow grdRow in GridView1.Rows)
{
    DropDownList drdList = (DropDownList)(GridView1.Rows[grdRow.RowIndex].Cells[1].FindControl("DropDownList1"));
    drdList.DataSource = dt;
    drdList.DataValueField = "Occupation";
    drdList.DataTextField = "Occupation";
    drdList.DataBind();
}

That is it. We now have a DropDownList in the GridView. We can use similar code with minor enhancements and an EditTemplate to display a DropDownList in edit mode while allowing the user to see a label in normal mode.

Get Individual DataKey value for multiple DataKeys

If you have a GridView with Multiple data key names like DataKeyNames="targetid,RequestID" and now you want get their individual values, you have to do the following steps,

string targetID= gv.DataKeys[e.RowIndex].Values[0].ToString();
string requestID= gv.DataKeys[e.RowIndex].Values[1].ToString();
Also you can use,
gv.DataKeys[e.SelectedIndex].Values["targetid"];
gv.DataKeys[e.SelectedIndex].Values["RequestID"];

This question has been asked many times, and recently over here.

Showing a DropDownList in a GridView using an EditItemTemplate

A very common question on the forums is about showing a DropDown in the GridView when the GridView is being edited. This is fairly easy to do using an EditItemTemplate.

The UI is farily simple. A GridView is shown with an Edit command in the first column and then three columns (Name, Age and Occupation) that would be holding the data. Once the user clicks on the Edit button, a DropDownList is shown in the Occupation column. Here is a snapshot of what the screen looks like when the Grid is in Edit mode.

UI_VIew.JPG

Here is the UI code. Note the use of the Edit CommandField and EditItemTemplate. A normal ItemTemplate is used for the scenario when the GridView is not in Edit mode.

<columns>
<asp:commandfield showeditbutton="True">
<asp:templatefield headertext="Name">
    <itemtemplate>
        <%# DataBinder.Eval(Container.DataItem, "Name")>
    </itemtemplate>
</asp:templatefield>
<asp:templatefield headertext="Age">
    <itemtemplate>
        <%# DataBinder.Eval(Container.DataItem, "Age")>
    </itemtemplate>
</asp:templatefield>
<asp:templatefield sortexpression="Occupation" headertext="Occupation">
    <edititemtemplate>
         <asp:dropdownlist id=""DropDownList1" runat="server">
    </edititemtemplate>
    <itemtemplate>
        <%# DataBinder.Eval(Container.DataItem,"Occupation")>
    </itemtemplate>
</asp:templatefield>
</columns>

Lets move to the code behind. Two important points here.

The first one is that the binding to the DropDownList must be done in the RowDataBound event and not the RowEditing event of the GridView. The RowEditingEvent does not understand e.Row. Also, the if condition in the RowDataBound method is important, especially the check for the DataControlRowState Edit. This is because RowDataBound is fired every time the GridView is bound and we only want to handle our scenario in the case when it is being edited.

The second important point (although not directly related to this sample), is the use of the RowEditing event. This is what dislays the DropDownList when the GridView enters Edit mode.

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow &&
    (e.Row.RowState & DataControlRowState.Edit) == DataControlRowState.Edit)
    {
        DropDownList dl = (DropDownList)e.Row.FindControl("DropDownList1");

        dl.DataSource = dt;
        dl.DataValueField = "Occupation";
        dl.DataTextField = "Occupation";
        dl.DataBind();
    }
}

protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
    GridView1.EditIndex = e.NewEditIndex;
    GridView1.DataBind();
}

There you go. That is all there is to displaying a DropDownList in Edit mode in a GridView.

Displaying an Image in a GridView

A frequent questions on the forum is about displaying an image in a GridView.

An ImageField is enough to do this. Here is what the web page and its code would look like (for a very simple scenario).

ImageGridView.JPG

All we need to do is bind to the DataImageUrlField field. As a note, an Images folder (containing the images) has been included in the project. This will be hosted on the server, along with the page itself.

DataTable dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("PictureUrl");

DataRow dr = dt.NewRow();
dr["Name"] = "Hydrangeas.jpg";
dr["PictureUrl"] = ResolveUrl("~/Images/Hydrangeas.jpg");
dt.Rows.Add(dr);

dr = dt.NewRow();
dr["Name"] = "Lighthouse.jpg";
dr["PictureUrl"] = ResolveUrl("~/Images/Lighthouse.jpg");
dt.Rows.Add(dr);

GridView1.DataSource = dt;
GridView1.DataBind();

The code behind is also fairly self explantory. A DataTable acts as the source to the GridView. Note the use of the ResolveUrl method to resolve the path of the image. That is all there is to get an image to display in a GridView.

Displaying a Running Total inside a GridView

Running a total for a numeric field inside a GridView is a topic that is often discussed. This can be easily be achieved by using a footer template. Take a look at the UI and code below.

RunningTotal.JPG

Adding ShowFooter = "true" is a necessity to show footers in a GridView. The FooterTemplate takes care of the rest.

The codebehind makes use of the RowDataBound method to do a sum.

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        sum = sum + Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "Salary"));
    }
    if (e.Row.RowType == DataControlRowType.Footer)
    {
        Label obj = (Label)e.Row.FindControl("Sum");
        obj.Text = Convert.ToString(sum);
    }
}

The sum is calculated in this method and then finally assigned to the label. That is all there is to dispaying the sum in a footer.

Displaying a Nested GridView

Displaying nested gridview's is a fairly common question. Its fairly simple to do using an ItemTemplate. The UI and code is below. Not much to explain there - a couple of text fields and two grids (one inside the other).

NestedGrid.JPG

This code is put into the Page_Load event.

DataTable dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("Age");

DataRow dr = dt.NewRow();
dr["Name"] = "Chris Harris";
dr["Age"] = "40";
dt.Rows.Add(dr);

dr = dt.NewRow();
dr["Name"] = "Sean Williams";
dr["Age"] = "39";
dt.Rows.Add(dr);

dr = dt.NewRow();
dr["Name"] = "Paul Newcombe";
dr["Age"] = "38";
dt.Rows.Add(dr);

GridView1.DataSource = dt;
GridView1.DataBind();

foreach (GridViewRow grdRow in GridView1.Rows)
{
    GridView nestedView = (GridView)(GridView1.Rows[grdRow.RowIndex].Cells[2].FindControl("GridView2"));
    nestedView.DataSource = dt;

    //For a sample, rowindex is passed here.
    //However, in a real environment, a key could be passed and this could fetch detail data
    nestedView.DataSource = LoadNestedData(grdRow.RowIndex);
    nestedView.DataBind();
}

LoadNestedData is the method that loads the nested grid. The code is not displayed here, but the code comments should give a general idea what this does. The DataSource to the nested gridview is set at runtime. Fairly simple.

History

Added 06/09/2011 : Get Individual DataKey value for multiple DataKeys
Added 06/09/2011 : Showing a DropDownList in a GridView in edit mode
Added 10/09/2011 : Displaying an Image in a GridView
Added 12/09/2011 : Importing an Excel file / Displaying a running total
Added 14/09/2011 : Displaying a Nested GridView

We are continuously looking for feedback from readers. If there is any other topic a reader wants us to include, please feel free to post about it in the comments section below. 

We will try to continue to update this article with more frequent questions from the Q&A and other forums.

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