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!