ASP.NET GridView use FindControl() on BoundField to manipulate field

RSolberg picture RSolberg · Jul 21, 2011 · Viewed 26k times · Source

I'm working with an old app that had hard coded columns for different locations, now that new locations are being added I decided to try and make things populate dynamically. One of the features of the app was displaying red text and bolding text when a status was deemed "bad". This was executed by using the "FindControl()" function from the cells within the selected row with TemplateFields.

Now that I've set this up to use a bound field, how would I go about changing the text color, size, etc. during the DataBound event?

BoundField Being Added To GridView

        BoundField statusField = new BoundField();
        statusField.DataField = "ExceptionStatusCode";
        statusField.HeaderText = "Status";
        statusField.SortExpression = "ExceptionStatusCode";
        this.gvView.Columns.Add(statusField);
        

DataBound Event For GridView

    protected void gvView_DataBound(object sender, EventArgs e)
    {
        foreach (GridViewRow row in this.gvView.Rows)
        {
            //NO LONGER WORKS, NEED TO KNOW HOW TO REPRODUCE
            //WHAT IS BELOW FOR BOUND FIELD
            Label lblPartStatus = ((Label) row.Cells[StatusColumn].FindControl("lblPartStatus"));
            if (lblPartStatus.Text == "BAD")
            {
                lblPartStatus.ForeColor = System.Drawing.Color.Red;
                row.ToolTip = "One or more locations is missing information!";
                row.BackColor = System.Drawing.Color.Salmon;
            }
        }
    }

Answer

James McCormack picture James McCormack · Jul 21, 2011

Years ago I wrote some code to help you find a cell index using the column's SortExpression, HeaderText or DataField. It's saved me lots of effort over the years, and you just call it like myRow.Cells[myRow.GetCellIndexByFieldHandle(myDataFieldName)]


public static class Utility
{
    /// <summary>
    /// Gets the ordinal index of a TableCell in a rendered GridViewRow, using a text fieldHandle (e.g. the corresponding column's DataFieldName/SortExpression/HeaderText)
    /// </summary>
    public static int GetCellIndexByFieldHandle(this GridView grid, string fieldHandle)
    {
        int iCellIndex = -1;

        for (int iColIndex = 0; iColIndex < grid.Columns.Count; iColIndex++)
        {
            if (grid.Columns[iColIndex] is DataControlField)
            {
                DataControlField col = (DataControlField)grid.Columns[iColIndex];
                if ((col is BoundField && string.Compare(((BoundField)col).DataField, fieldHandle, true) == 0)
                    || string.Compare(col.SortExpression, fieldHandle, true) == 0
                    || col.HeaderText.Contains(fieldHandle))
                {
                    iCellIndex = iColIndex;
                    break;
                }
            }
        }
        return iCellIndex;
    }

    /// <summary>
    /// Gets the ordinal index of a TableCell in a rendered GridViewRow, using a text fieldHandle (e.g. the corresponding column's DataFieldName/SortExpression/HeaderText)
    /// </summary>
    public static int GetCellIndexByFieldHandle(this GridViewRow row, string fieldHandle)
    {
        return GetCellIndexByFieldHandle((GridView)row.Parent.Parent, fieldHandle);
    }
}

Once you have the cell, I suggest you manipulate it by setting Cell.CssClass, and then using CSS to style it accordingly. Steer clear of inline style, which is what you get when you set ForeColor, BackColor etc.