views:

5139

answers:

4

Here is my DataList:

<asp:DataList id="DataList" Visible="false" RepeatDirection="Horizontal" Width="100%" HorizontalAlign="Justify" RepeatLayout="Flow" runat="server">
        [Contents Removed]
</asp:DataList>

This generates markup that has each item wrapped in a span. From there, I'd like to break each of these spans out into rows of three columns. Ideally I would like something like this:

<div>
 <span>Item 1</span>
 <span>Item 2</span>
 <span>Item 3</span>
</div>
<div>
 <span>Item 4</span>
 <span>Item 5</span>
 <span>Item 6</span>
</div>
[etc]

The closest I can get to this is to set RepeatColumns to "3" and then a <br> is inserted after every three items in the DataList.

 <span>Item 1</span>
 <span>Item 2</span>
 <span>Item 3</span>
<br>
 <span>Item 4</span>
 <span>Item 5</span>
 <span>Item 6</span>
<br>

This gets me kind of close, but really doesn't do the trick - I still can't control the layout the way I'd like to be able to.

Can anyone suggest a way to make this better? If I could implement the above example - that would be perfect, however I'd accept a less elegant solution as well - as long as its more flexible than <br> (such as inserting a <span class="clear"></span> instead of <br>).

+1  A: 

I may be confused, but why not just use a repeater and a custom item template?

Mike Robinson
Maybe I've been staring at my computer too long today (well, I know I have...) but I'm not seeing any easy solution with a repeater either, I'd welcome an example of this as well. I believe it would be reasonable for me to replace the DataList with a Repeater.
Ian Robinson
+1  A: 

If you really needed to use a datalist for some reason instead of implementing this as a repeater, you can try doing something like this:

<asp:DataList ID="dataList" runat="server" RepeatDirection="Horizontal" Width="100%" HorizontalAlign="Justify" RepeatLayout="Flow" OnItemDataBound="dataList_ItemDataBound">
    <HeaderTemplate>
        <div>
    </HeaderTemplate>
    <SeparatorTemplate>
        </div><div>
    </SeparatorTemplate>
    <ItemTemplate>
        <%# Container.DataItem %></ItemTemplate>
    <FooterTemplate>
        </div></FooterTemplate>
</asp:DataList>


protected void dataList_ItemDataBound(object sender, DataListItemEventArgs e) {
    if (e.Item.ItemType == ListItemType.Separator) {
        if ((e.Item.ItemIndex + 1) % 3 != 0) {
            e.Item.Controls.Clear();
        }
    }
}
DavGarcia
Thanks David. This solution will work, but what about the repeater makes this so much easier to implement? Thanks again.
Ian Robinson
You'd actually use the exact some approach but with a Repeater. The DataList has overhead involved for doing things like rendering content in tables, which you are trying to usurp. Also it is derived from a WebControl whereas the Repeater is derived from Control.
DavGarcia
Thanks David, I implemented this as my solution (using a repeater). I appreciate the help.
Ian Robinson
A: 

You can achieve your desired layout using CSS without altering the original generated markup. Since span tags are displayed inline by default, switching to inline-block and specifying a width of 33% on those spans should do the trick.

Or more specifically, set the CssClass property of your DataList control to a value such as "threecolumns".

Define the following css style:

<style type="text/css">
.threecolumns span 
{
    display: inline-block;
    width: 33%;
}
</style>

VS2008 might tell you that inline-block isn't a valid setting for the display property. I wouldn't worry about that too much since almost every browser supports it.

Ken Browning
A: 

add this RepeatColumns="100000"

ivica