Obviously, grid-view would give you desired tabular layout (probably with the minimal efforts with Auto Generated Columns).
However, if paging, sorting, editing are note required then I would rather user Repeater control. The main reason being precise control over the mark-up. For example, grid-view does not support elements such as <colgroup>
or <thead>
(again, these elements may not be needed for your layout). If paging/sorting/editing etc is needed then ListView is better choice.
As far as, showing multiple tables goes, you can use nested controls - for example, repeater/list-view nesting a grid-view.
EDIT:
You are not very clear about the structure of data that you have and also about the exact layout that you want. So here's what I am assuming - you have a single List<Subscriber>
containing both root subscribers and their children. And in the layout, you want one table for root subscribers followed by multiple tables - one for each root subscriber's children.
Mark-up will be something like
<asp:Repeater runat="server" ID="Outer" >
<HeaderTemplate>
<%-- Put a grid here for parent -->
<asp:GridView runat="server" ID="Root" DataSource='<%# GetRootSubscribers() %>' >
... column def etc
</asp:GridView>
</HeaderTemplate>
<ItemTemplate>
<!-- Put a grid here for children for current root subsriber -->
<asp:GridView runat="server" ID="Child" DataSource='<%# GetChildSubscribers(Eval("MemberID")) %>' >
... column def etc
</asp:GridView>
</ItemTemplate>
</asp:Repeater>
This will be supported by two code-behind methods such as
protected IEnumerable<Subscriber> GetRootSubscribers()
{
// I am not sure how you decide if a subscriber is a parent or not, I have just
// illustrated a condition where you have a parent id field to indicate the same
return allSubscribers.Where(s => s.ParentID == null);
}
protected IEnumerable<Subscriber> GetChildSubscribers(object memberId)
{
// I am not sure how you decide a child subscriber, I have just
// illustrated a condition where you have a parent id field to indicate the same
return allSubscribers.Where(s => s.ParentID.Equals(memberId));
}
// bind the outer repeater to root list
Outer.DataSource = GetRootSubscribers();
Outer.DataBind();
Hope this will give you some idea about how to proceed.