0

I need to bind 15-20 fields to Repeater in 3-4 files (so, total number of data-bound fields must be about 60). I read few technical articles how to do that, understood pros and cons of both approaches.

Eval() is simple and elegant, but uses reflection, therefore it is slow. Well, I do not care about performance. 0.1s or 0.2s to load a page - who cares. Maintainability and simplicity of code are my goals. The main disadvantage of Eval() as I see - it is not strongly-typed. Moreover, it accepts field names as strings(?!!). So, if I someday refactor my code and rename fields of underlying object - my code will be broken silently and start to crash at run-time. Am I correct?

((TYPE)Container.DataItem).Field looks ugly (especially, when repeated many times). But it is strongly-typed and excludes possible bugs. Right?

I am interested what approach professionals use in enterprise applications.

Denis
  • 3,653
  • 4
  • 30
  • 43
  • ".1s or .2s to load a page - who cares"? Your users do. From [Google](http://googleresearch.blogspot.co.uk/2009/06/speed-matters.html) - "Our experiments demonstrate that slowing down the search results page by 100 to 400 milliseconds has a measurable impact on the number of searches per user of -0.2% to -0.6%". For ecommerce sites... you could be losing money the slower your site is. – MikeSmithDev Jan 21 '14 at 16:05

2 Answers2

3

I recommend using a Strongly-Typed control such as a ListView: http://weblogs.asp.net/dwahlin/archive/2013/03/26/asp-net-4-5-web-forms-features-strongly-typed-data-controls.aspx

In .NET 4.5 these controls have been optimized and will provide you the best of both worlds.

Chris Bohatka
  • 363
  • 1
  • 4
  • 14
  • Great answer. This is what I need. But unfortunately it is supported only on Visual Studio 2012, while I am still on 2008. I googled around and found this http://stackoverflow.com/questions/12390175/targeting-net-framework-4-5-via-visual-studio-2010/13240050#13240050 solution. Somebody knows will it work on 2008? – Denis Jan 21 '14 at 17:45
2

Sorry for the long reply!

I'm not sure if I follow you exactly with the 3-4 files but here is what we tend to do. Also, let me first say that 99.9% of the time we use a repeater because of flexibility you have with layout and formatting of the data. Yes there are other controls that make basic data-binding easier with some more built in features but most times you don't need all the overhead.

We typically create a class to bind to the repeater. So if you need to combine multiple sources of data you can instantiate the class with the different predefined inputs. At this point all you need to do is create properties for each of the fields you want to bind to the repeater. And with the properties you can format the data however you like. For example combine first and last name into a fullname property. So if you need to refactor code because someone wants you to change the name format all you have to do is change the format class and your repeater never has to change.

<asp:Repeater ID="rptCalls" runat="server">

<ItemTemplate>      

            <tr runat="server" class='<%# Eval("RowClass") %>'>
                <td style="width: 40px;"><asp:Button ID="btnUpdate" runat="server" Text="View" CommandArgument='<%# Eval("Id") %>' CssClass="button" OnCommand="btnUpdate_Command" /></td>                  
                <td runat="server"><%# Eval("CallCount")%></td>
                <td style="width: 40px; white-space: nowrap; text-align: center;"><asp:Literal runat="server" Text='<%# Eval("TimeCalled") %>'></asp:Literal></td>                  
                <td><asp:Literal runat="server" Text='<%# Eval("Notified") %>'></asp:Literal></td>
                <td><asp:Literal runat="server" Text='<%# Eval("PatientName") %>'></asp:Literal></td>
                <td><asp:Literal runat="server" Text='<%# Eval("RequestorData") %>'></asp:Literal></td>
            </tr>
            </ItemTemplate>
        </asp:Repeater>

Here is an example of some of the fields in the class.

public int Id { get { return notification.CallRequest.Id; } }

    public string RowClass
    {
        get
        {
            return overduePolicy.IsOverdue() ? "overdue" : "";
        }
    }

    public string SearchCssClass
    {
        get
        {
            return notification.CallRequest.IsVoided ? "voided" : "";
        }
    }

The rowclass property is an example of something you can do with the properties. If you notice the opening TR tag it's Eval statement is Eval("RowClass") but it's assigned to the css "class" tag on TR. The RowClass property in the actual class checks a value and sets a specific text based on true false. This then highlights the row with a css style depending on true/false value.

Just an example of the freedom you have with repeaters.

Sorry for the long reply but I know when I'm stuck I like the same kind of feedback.

GOOD LUCK!

Jon
  • 61
  • 3
  • Well, your answer is exactly what I have now: separate classes for each `Repeater`, preformatting of all required fields in `Page_Load` and binding to `Repeater`. I like this architecture. You uses `Eval("Field")` as I see. But it is possible to use `((TYPE)Container.DataItem).Field` there as well. This is the question. – Denis Jan 21 '14 at 17:15
  • You can but there are tradeoffs for each. As you mentioned above, Eval does late binding and uses reflection but you also only have to touch your viewmodel for changes. With dataitem, you have to cast which has better performance, but you have more maintenance. I think this is a business decision you need to make to decide is the performance hit ok for less modifications or not. That testing and performance is only something you decide based on all the factors within your organization. Everything else at this point would just be opinion/comparison based on what it seems you already know. – Jon Jan 21 '14 at 17:25