Devils Work

—Blog By DotNetRuler

Archive for October, 2009

How to make a Gridview Row Color/ Cell Color/ Text Color

Posted by DotnetRuler on October 13, 2009

In this article I am going to explain how we can change the Gridview Row Color/ Cell Color/ Text Color. So many people asked in the emails for my previous article why I have used Template Columns rather than bound fields. I just want to make them clear this question (going to explain it at the end of the article) because, I am going to use Template Fields again in this article 🙂

TASK: In this article we are trying to display some information from AdventureWorks database, Employee table, and if the employee pay rate is more than 25 we are going to change the color of the row/cell/text.

GridView Row Color

Here is the html markup for the grid

<asp:GridView ID=”GridView1″ runat=”server” OnRowDataBound=”GridView1_RowDataBound” AllowSorting=”true” AllowPaging=”true” PageSize=”10″ AutoGenerateColumns=”false” >


                <asp:TemplateField HeaderText=”ID”>


                        <asp:Label runat=”server” ID=”lblNationalID” Text='<%#Eval(“NATIONALIDNUMBER”)%>’ />



                <asp:TemplateField HeaderText=”Title”>


                        <asp:Label runat=”server” ID=”lblTitle” Text='<%#Eval(“TITLE”) %>’ />



                <asp:TemplateField HeaderText=”Manager ID”>


                        <asp:Label runat=”server” ID=”lblMgrID” Text='<%#Eval(“MANAGERID”) %>’ />



                <asp:TemplateField HeaderText=”Gender”>


                        <asp:Label runat=”server” ID=”lblGender” Text='<%#Eval(“GENDER”) %>’ />



                <asp:TemplateField HeaderText=”Rate”>


                        <asp:Label runat=”server” ID=”lblRate” Text='<%#Eval(“RATE”) %>’ />





The Above markup is pretty simple if you follow my previous article as I just used template field’s and Item templates.  The only thing special piece from the previous article is OnRowDataBound=”GridView1_RowDataBound”. I implemented the rowdatabound event. This event fires after we call DataBind() method.  If we want to modify data or check certain conditions before displaying it to the user this is the correct place to do the changes. As we need to change the row color/ text color/ cell color before displaying to the user this we need this event.

The rowdatabound signature is as follows.

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)

As we can see, it has two parameters. The first one is sender, so in this case it is gridview which is calling this event. And the second one is GridViewRowEventArgs.  This is very helpful parameter which carries all the row information like what kind of row (data row/ header row/ footer row)? What is the row state (Alternate/ Insert/ Edit/ Selected …)? And many more, we can explore it at here.

Coming to the c# code my page load event is as follows.

protected void Page_Load(object sender, EventArgs e)


        if (!Page.IsPostBack)


            using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings[“AdventureWorksConnectionString”].ConnectionString))



                using (SqlCommand comm = new SqlCommand(“GetEmployeeWithSalaries”, conn))


                    comm.CommandType = CommandType.StoredProcedure;

                    SqlDataAdapter da = new SqlDataAdapter(comm);

                    DataSet ds = new DataSet();


                    GridView1.DataSource = ds;






I am just opening a connection and calling a stored procedure, getting the data back into a dataset and binding to the grid.

As I said earlier as soon as the DataBind() called, our RowDataBound event fires. The event code is as follows.

    /// <summary>

    /// Row Data Bound Event fires after gridview calls DataBind() method.

    /// So if you want to data or check certain conditions before displaying it to the user

    /// this may be correct place to do the changes.

    /// </summary>

    /// <param></param>

    /// <param></param>

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)


        // Check the row type, if “datarow” enter

        if (e.Row.RowType == DataControlRowType.DataRow)


            // grab the Label Control.

            Label lblRate = e.Row.FindControl(“lblRate”) as Label;


            // get the value from the datasoure like this

            Double rate = Convert.ToDouble(Convert.ToString(DataBinder.Eval(e.Row.DataItem, “Rate”)));


            // get the whole dataItem, if u want to access more columns from database like this           

            // It is a datarowview if u bind dataset/datatable

            // DataRowView dr = e.Row.DataItem as DataRowView;


            // after you got the datarowview u can access the column value like this.

            // string s = dr[“Rate”].ToString();


            // It is a datarowview if u bind List<Employee>

            // Employee employee = e.Row.DataItem as Employee;


            // after you got the datarowview u can access the property value like this.

            // string rate = employee.Payrate;


            if (rate > 25.00)


                // grab the cell where that label resides

                DataControlFieldCell d = lblRate.Parent as DataControlFieldCell;


                // change the backcolor like this

                d.BackColor = System.Drawing.Color.Red;


                // change the row color like this

                e.Row.BackColor = System.Drawing.Color.LightBlue;


                // change the text color like this

                lblRate.ForeColor = System.Drawing.Color.White;




If we see in the code, I am checking a condition such that if the row is of type datarow then only it goes into that loop as we don’t need to change any colors in the header/footer. So once the row is of type datarow it goes into the loop. We need to get the label control from the row using findcontrol method. FindControl method takes the control name as the parameter. So as we can see in the code we are passing the “lblRate” which is the name of the label control in the Gridview html markup. Findcontrol returns a web.control, so we need to cast it to the appropriate type, in our case it is label.

Next step is needed to get the rate. we can get it in different ways. The basic thing is GridViewEventArgs carries the whole row data in the e.Row.DataItem Object. This object varies with the type of data source. If we bind dataset/datatable it would be datarowview, if it is List<T> it would be of type T. We need to cast it to the appropriate type and access the inner properties of the object.

Last step is needed to change the color

Change the color of row: GridViewEventArgs has a property called e.Row.BackColor we can assign a color to it. This will do the work for us.

Change the color of cell: so we don’t know what cell we need to change the color. We just know that we need to change the color of the cell where our rate column resides and in our example we placed the lblRate control in that cell. So cell will be the parent of our label control. So get the parent using parent property of the label and cast it to the appropriate type. I know some people might be confused by now as I am always saying “cast it to the appropriate type”. To find out the appropriate type just put a break point and check lblRate.Parent.GetType(), which will gives us the parent type. No one is going to know this for the first time. We just need to do some reverse engineering to achieve what we need. Once you got the parent (cell) we can change the backcolor using backcolor property of it.

Change the text color: The text that we r displaying is label controls content. So we just need to change the label forecolor property.

Lastly Why TempalteFields? Why not BoundFields?

Note:  some people will think why don’t we achieve this functionality with the boundfieldcolumns? Why templatefields?

The reason is because, it’s very hard to manage the code and if we use cells [index] what if we want to change the column position in future? We need to change the code base again. In the above case we just need to change the markup if you use tempaltefields which we can do it easily and which does not need a project build. What if we need to place multiple controls in the same column? And there will be so many other conditions to. So this is the reason why we are using Tempaltefields rather than Boundfields.

Note: WordPress text editor has some problems, I will re-edit the post when it is ready.

Happy Coding .

Keep Rocking as always 🙂


Posted in ASP.NET, Grid View | 11 Comments »