Ответ 1
Лучше использовать элемент управления DataList intstead, поскольку он обладает интересными свойствами RepeatColumns и RepeatDirection.
Я хотел бы иметь возможность использовать элемент управления ASP.Net Repeater для создания таблицы HTML, которая имеет три столбца и столько строк, сколько требуется.
Например, если данные должны были выглядеть как
"Фил Хьюз"
"Энди Петит"
"CC Sabathia"
"AJ Burnett"
"Хавьер Васкес"
Я хочу, чтобы результирующая таблица была как
<table>
<tr>
<td>Phil Hughes</td>
<td>Andy Petite</td>
<td>CC Sabathia</td>
</tr>
<tr>
<td>AJ Burnett</td>
<td>Javier Vazquez</td>
<td></td>
</tr>
</table>
Как я могу это сделать?
Лучше использовать элемент управления DataList intstead, поскольку он обладает интересными свойствами RepeatColumns и RepeatDirection.
Повторитель не является идеальным контролем для этого. Если вы используете .NET 3.5, вы должны использовать ListView. Вот пример, который делает то, о чем вы просите.
<asp:ListView ID="myListView" runat="server"
DataSourceID="YOURDATASOURCE" GroupItemCount="3">
<LayoutTemplate>
<table>
<tr>
<td>
<table border="0" cellpadding="5">
<asp:PlaceHolder runat="server" ID="groupPlaceHolder"></asp:PlaceHolder>
</table>
</td>
</tr>
</table>
</LayoutTemplate>
<GroupTemplate>
<tr>
<asp:PlaceHolder runat="server" ID="itemPlaceHolder"></asp:PlaceHolder>
</tr>
</GroupTemplate>
<ItemTemplate>
<td>
<%# Eval("FullName") %>
</td>
</ItemTemplate>
</asp:ListView>
Намного проще, чем все приведенные здесь примеры; Вам не нужно использовать представление списка или делать что-либо в коде.
<asp:Repeater ID="ExampleRepeater" runat="server" >
<HeaderTemplate>
<table>
<tr>
<th> Column 1
</th>
<th> Column 2
</th>
<th> Column 3
</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:LinkButton ID="RemoveButton" runat="server" Text='Remove' CommandName="Remove"
CommandArgument='<%# Eval("ID") %>' CausesValidation="false"></asp:LinkButton>
</td>
<td>
<asp:LinkButton ID="EditLink" runat="server" Text='<%# Eval("Name") %>'
CommandName="Edit" CommandArgument='<%# Eval("ID") %>' CausesValidation="false"></asp:LinkButton>
</td>
<td>
<asp:Label ID="CommentTextBox" runat="server" Text='<%# Eval("Comment") %>' />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
<asp:Repeater runat="server" DataSourceID="testds">
<HeaderTemplate>
<table class="items">
</HeaderTemplate>
<ItemTemplate>
<%# (Container.ItemIndex + 3) % 3 == 0 ? "<tr>" : string.Empty%>
<td><img src='/blablabla/<%# Eval("id") %>.jpg' alt="" /></td>
<%# (Container.ItemIndex + 3) % 3 == 2 ? "</tr>" : string.Empty%>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
Я предполагаю, что у вас есть все эти имена в 5 строках данных, и вы хотите распространять их по 3 столбцам в ретрансляторе и не иметь двух строк данных с тремя полями, которые были бы прямолинейными. Исходя из моего предположения, ваши данные выглядят примерно так:
DataTable
(или независимо от вашего источника):
ID Name
---------------
1 Bob
2 John
3 Joe
4 Mary
5 Mike
Вы можете сделать это с помощью Repeater
и Literal
с небольшой логикой в OnDataBinding
событии Literal
.
Сначала определите свой Repeater
:
<asp:Repeater ID="repeater" runat="server">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<asp:Literal ID="litItem" runat="server" OnDataBinding="litItem_DataBinding" />
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
Далее вам понадобится константа для полных столбцов и две глобальные переменные для отслеживания операции привязки. Определите их так:
public partial class _YourPage : System.Web.UI.Page
{
private const int _repeaterTotalColumns = 3;
private int _repeaterCount = 0;
private int _repeaterTotalBoundItems = 0;
Затем вам нужно будет реализовать OnDataBinding, чтобы выполнить всю работу:
protected void litItem_DataBinding(object sender, System.EventArgs e)
{
Literal lt = (Literal)(sender);
_repeaterCount++;
if (_repeaterCount % _repeaterTotalColumns == 1)
{
lt.Text = "<tr>";
}
lt.Text += string.Format("<td>{0}</td>", Eval("Name").ToString());
if (_repeaterCount == _repeaterTotalBoundItems)
{
// Last item so put in the extra <td> if required
for (int i = 0;
i < (_repeaterTotalColumns - (_repeaterCount % _repeaterTotalColumns));
i++)
{
lt.Text += "<td></td>";
}
lt.Text += "</tr>";
}
if (_repeaterCount % _repeaterTotalColumns == 0)
{
lt.Text += "</tr>";
}
}
Затем убедитесь, что при привязке Repeater
вы сохраняете общий счет:
_repeaterTotalBoundItems = yourDataTable.Rows.Count;
repeater.DataSource = yourDataTable;
repeater.DataBind();
Выводимый результат:
<table>
<tr><td>Bob</td>
<td>John</td>
<td>Joe</td></tr>
<tr><td>Mary</td>
<td>Mike</td><td></td></tr>
</table>
Возможно, вы, возможно, улучшите код DataBinding
, но я просто сокрушил его, чтобы дать основную предпосылку о том, как достичь своей цели. Если DataBinding
необходимо выполнить множество операций конкатенации строк, вам следует перейти на использование StringBuilder
, а затем просто назначить Literal
в последней операции.
Или просто используйте div в репитере, а затем решите проблемы с высотой/шириной с помощью CSS.