views:

31

answers:

1

I'm currently using a GridView and I want to set the CssClass for the Row depending on a property of the object that the row is being bound to.

I tried the following but it does not work (see comments):

<asp:GridView id="searchResultsGrid" runat="server" AllowPaging="true" PageSize="20" AutoGenerateColumns="false">

<!-- The following line doesn't work because apparently "Code blocks 
aren't allowed in this context: -->
  <RowStyle CssClass="<%#IIF(DataBinder.Eval(Container.DataItem,"NeedsAttention","red","") %>

  <Columns>
<!--............-->
  </Columns>
</asp:GridView>

Now I could simply handle the GridView's RowDataBound event and change the css class of the row there...but I'm trying to keep a clear separation between the UI and the page/business logic layers.

I have no idea how to accomplish this and I'm looking forward to hearing any suggestions.

Thanks,

-Frinny

A: 

You cannot do this in declarative markup.

Nearly all of GridView's declarative properties (including GridView.RowStyle) are grid-level settings rather than row-level. Apart from TemplateFields , they are not bound data containers, so they don't have access to the data in their rows.

If you want to keep this logic in the .aspx template, your only real option is to use template fields and manipulate their contents:

<asp:TemplateField>
    <ItemTemplate>
        <span class="<%# ((string)Eval("property3")) == "NeedsAttention" ? "red" : string.Empty %>">
            <%# Eval("property1") %>
        </span>
    </ItemTemplate>                        
</asp:TemplateField>

Depending on what you want to do, this may be awkward - you don't have access to the containing <td> (or <tr> for that matter) and you'll have to repeat the formatting for each cell.

The GridView class goes to a lot of lengths to hide the details of HTML and styling from you. After all you could create a GridView control adapter that wouldn't even render as HTML tables. (Unlikely though that may be.)

So even though you're trying to avoid it, you're probably best off dealing with this in a OnRowDataBound handler - or use a Repeater (if that's appropriate).

Jeff Sternal
Yeah I thought about this too but I wasn't to happy with the fact that I would have to do this for every TemplateField and BoundField in the row. It is going to be awkward. Maybe I'll just bite the bullet and handle the OnRowBound event. So much for keeping my layers separate.
Frinavale
Thanks Jeff. As disappointing as this answer is, at least you have confirmed that it's impossible to do this.
Frinavale
You bet - and I'm sorry to bring the bad news. The GridView is what it is, and has fathered many disappointments; I try to avoid it when I can. When its advantages (such as they are) are irresistable, I just bite the bullet too.
Jeff Sternal