views:

682

answers:

2

I have a Repeater contol bound to a custom object (an EntitySpaces query) and have noticed there are a couple of ways to conditionally format the values being displayed.

1) From my aspx I can call a method in my code-behind and pass through the bound value and use that to drive any conditional logic:

        <a class="star" href="<%#MakePackageSelectionUrl((int)DataBinder.Eval(Container.DataItem, "PackageId"))%>">

and then in the code-dehind:

    protected string MakePackageSelectionUrl(int packageId)
    {
              return string.Format("/Packages/NoAjax/ToggleStar.aspx?p={0}&amp;s={1}&amp;st={2}", packageId, _streamId, (int)_phase);
    }

2) I can hook into the ItemDataBound event, retrieve e.Item.DataItem as a DataRowView and then go crazy:

    protected void PackageList_ItemDataBound(Object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) { return; }

        DataRowView details = (DataRowView)e.Item.DataItem;

        EncodePackageName(e, details);
        EncodeStatusName(e);
        DisplayStarImage(e, details);
    }

    private static void EncodePackageName(RepeaterItemEventArgs e, DataRowView dr)
    {
        HtmlAnchor p = (HtmlAnchor)e.Item.FindControl("packageLink");
        if (p != null)
        {
            p.HRef = string.Format("/Packages/View.aspx?p={0}", dr["packageId"]);
            p.InnerHtml = HttpUtility.HtmlEncode((string)dr["packageName"]);
        }
    }

I've also noticed that using e.Item.FindControl() in the code-behind requires runat="server" on the control in the aspx which has a nasty habit of encoding ids and generally messing up the HTML.

I'm keen to hear from anyone that has come up with a nice approach for dealing with these sorts of issues.

+1  A: 

Keep It Simple.

The more code you write (even if it is repetitive), the more errors may sneak in.

I prefer the first method, since you don't need the event handler, and keep all your formatting in a separate class if used more than once.

devio
+1  A: 

In this case all you are doing is manipulating some HTML so I would use the first method. The second method is appropriate where you need to check the item being databound and make changes to server controls in response (for example binding nested lists).

Note also that calls to DataBinder.Eval() are expensive - it uses reflection. You will get better performance using explicit casting like so:

MakePackageSelectionUrl(((System.Data.DataRowView)Container.DataItem)["PackageId"])

For reference: http://msdn.microsoft.com/en-us/library/ms998549.aspx. See section on minimising calls to DataBinder.Eval.

flesh