I experienced the same thing. An alternative would be to add a Label control and set the properties on that instead.
Rather than using a BoundField, use a TemplateField. Assuming that your data is returning an indexable item:
<asp:GridViewControl runat="server" ID="GridView2" AutoGenerateColumns="false">
<asp:BoundField HeaderText="Field0" DataField="[0]" />
<asp:BoundField HeaderText="Field1" DataField="[1]" />
<asp:TemplateField HeaderText="Monkey1" />
<asp:TemplateField HeaderText="Monkey2" />
</asp:GridViewControl>
Then in the code-behind:
protected void GridView2_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var data_item = e.Row.DataItem; // Can use "as <type>;" if you know the type.
if (data_item != null)
{
for (int i = 2; i <= 3; i++)
{
var cell_content = new Label();
e.Row.Cells[i].Controls.Add(cell_content);
cell_content.Text = data_item[i];
if (data_item[i].Contains("monkey"))
{
cell_content.Attributes.Add("class", "monkey bold");
}
else
{
cell_content.Attributes.Add("class", "nomonkey bold");
}
}
}
Of course an alternative would be to add the Label in the TemplateField -> ItemTemplate declaration with an ID and use "Cells[i].FindControl("label_id")".