views:

249

answers:

2

I would like the rows of my GridView to have strikethrough based on a bound data value called IsObsolete. I tried to do this:

<RowStyle BackColor="#EFF3FB" Font-Strikeout='<%# Bind('IsObsolete') %>' />

But obviously this doesn't parse. I'd rather not do this in GridView.DataBound(). Any other ideas?

A: 

I do this by applying a style on the DataBinding event of one of my controls in a template. Example:

<asp:GridView ID="grdYourGrid" runat="server" AutoGenerateColumns="False">
    <Columns>
        <asp:TemplateField HeaderText="SomeTitle">
            <ItemTemplate>
                <asp:HyperLink ID="hrefYourLink" runat="server"
                    NavigateUrl="Somepage.aspx?id={0}" 
                    OnDataBinding="hrefYourLink_DataBinding"></asp:HyperLink>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

Then implement the OnDataBinding event:

protected void hrefYourLink_DataBinding(object sender, System.EventArgs e)
{            
    HyperLink link = (HyperLink)(sender);
    GridViewRow row = (GridViewRow)(link.Parent.Parent);
    if ((bool)(Eval("IsObsolete"))
    {
        row.CssClass = "StrikeThroughStyle";
    }
    link.Text = HttpUtility.HtmlEncode(((int)(Eval("ID"))).ToString());
    link.NavigateUrl = string.Format(link.NavigateUrl, Eval("ID").ToString());
}

This is just an quick example with a column with a link that gets modified based on the databinding as well but you should be able to get the gist of if an tweak it to suit your needs. I like doing it on the databinding because I do no binding inline in my aspx code.

Kelsey
@Matthew Jones did you ever figure this out? If you need more help just leave a comment or edit your question and I will see what I can do.
Kelsey
A: 

Since the RowStyle element is applicable to the entire grid, the only way to accomplish what you want would be to have TemplateItems set for all columns and apply a CssClass to each column based on that same data value.

I'm not sure for your reasoning for avoiding the DataBound event for doing this as that would be the simplest way to accomplish it.

You might also try using a formatting function and itemstyles. Stealing a tidbit of code from above and changing it:

<%

public string GetObsoleteClass(string obsolete)
{
    bool obs = Convert.ToBoolean(obsolete);
    obs ? return "myObsoleteClass" : return "myNotObsoleteClass";
}

%>
<asp:GridView ID="grdYourGrid" runat="server" AutoGenerateColumns="False">
    <Columns>
        <asp:TemplateField HeaderText="SomeTitle">
            <ItemTemplate>
                <asp:HyperLink ID="hrefYourLink" runat="server"
                    NavigateUrl="Somepage.aspx?id={0}" 
                    OnDataBinding="hrefYourLink_DataBinding"></asp:HyperLink>
            </ItemTemplate>
              <itemstyle CssClass='<%# Eval("isObsolete") %>'>
              </itemstyle>
        </asp:TemplateField>
        <asp:boundfield
            sortexpression="LastName"
            datafield="LastName"
            headertext="LastName">
              <itemstyle CssClass='<%# Eval("isObsolete") %>'>
              </itemstyle>
        </asp:boundfield>
    </Columns>
</asp:GridView>
Joel Etherton
The Css can be set at the Row level and doesn't need to be set on each item individually unless you want to override something. Also I do it on an item DataBinding event because I usually have at least one of these defined and rarely implement any other DataBound events so it's easy to just add it to the first items DataBinding event. Also if you want to color entire rows a different color my methods works well.
Kelsey
@Kelsey - That's what he's trying to do - override something. I agree that using the event is the preferred method, but he specifically indicated in the question that he didn't want to use the event.
Joel Etherton