Here's an idea. This assumes that the number of items to display vertically before wrapping is a fixed number, or at least a number that can be determined by the server (see the VerticalWrapLimit constant). I.e. it is not related to the height of the users's browser.
<script runat="server">
void Page_Load(object sender, EventArgs e)
{
rptVerticalWrap.DataSource = new[] {
new { ID = 1, Name = "ABC" },
new { ID = 2, Name = "BCD" },
new { ID = 3, Name = "CDE" },
new { ID = 4, Name = "DEF" },
new { ID = 5, Name = "EFG" },
new { ID = 6, Name = "FGH" },
new { ID = 7, Name = "GHI" },
new { ID = 8, Name = "HIJ" },
};
rptVerticalWrap.DataBind();
}
int count;
const int VerticalWrapLimit = 5;
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<% count = 0; %>
<div style="float:left;">
<asp:Repeater ID="rptVerticalWrap" runat="server">
<ItemTemplate>
<%
if (count % VerticalWrapLimit == 0 && count > 0)
{
%></div><div style="float:left;"><%
}
count++;
%>
<div>
<asp:Label runat="server" Text="ID: " /><asp:TextBox runat="server" Text='<%# Eval("ID") %>' />
<asp:Label runat="server" Text="Name: " /><asp:TextBox runat="server" Text='<%# Eval("Name") %>' />
</div>
</ItemTemplate>
</asp:Repeater>
</div>
</div>
</form>
</body>
</html>
For this sort of problem, I think what you need to do is identify what you want the resulting HTML to look like first, then write the ASP code to generate that.
In this case, I wrapped each vertical column of data in a with style="float:left;". I used a class scoped "count" variable in order to identify when I needed to close off the current div and start a new one. The count variable has to be a class-level variable because the contents of the Repeater's ItemTemplate has a different scope than the rest of the page.