How to create a three column table in ASP.Net Repeater

大憨熊 提交于 2019-11-27 15:01:44

It's better to use a DataList control intstead as it has the interesting properties RepeatColumns and RepeatDirection.

Merrimack

Repeater is not the ideal control to do that. If you're using .NET 3.5 you should use ListView instead. Here's an example that does what you're asking for.

<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>

Much simpler than all the examples listed here; You don't need to use a list view or do anything in the code behind.

  <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>

I am assuming you have all those name in 5 rows of data and you want to spread it across 3 columns in a repeater and not have 2 rows of data with 3 fields which would be straight forward. Based on my assumption your data is something like:

DataTable (or whatever your source is):

ID      Name
---------------
1       Bob
2       John
3       Joe
4       Mary
5       Mike

You can do it using a Repeater and a Literal with a little logic on the OnDataBinding event of the Literal.

First define your 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>

Next you will need a constant for the total columns you want and two global variables to track the binding operation. Define them like so:

public partial class _YourPage : System.Web.UI.Page
{
    private const int _repeaterTotalColumns = 3;
    private int _repeaterCount = 0;
    private int _repeaterTotalBoundItems = 0;

Then you will need to implement the OnDataBinding to do all the custom work:

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>";
    }
}

Then make sure when you bind your Repeater you are saving the total count:

 _repeaterTotalBoundItems = yourDataTable.Rows.Count;
 repeater.DataSource = yourDataTable;
 repeater.DataBind();

The output produced would be:

<table>    
<tr><td>Bob</td>
<td>John</td>
<td>Joe</td></tr>
<tr><td>Mary</td>
<td>Mike</td><td></td></tr>
</table>

You could probably improve the DataBinding code but I just rattled it off to give the basic premise of how to accomplish your goal. If the DataBinding needs to do a lot of string concat operations, you should probably switch to to using a StringBuilder and then just assign the Literal in the last operation.

Or just use a div in the repeater and then solve the hight/width issues with CSS.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!