Using the ListView control in Tiled mode (Part 1)

Version : VS 2008 RTM

The ListView control is a data bound control new to the ASP.net web controls collection. The ListView control, from a UI standpoint, gives full control over how the html should be rendered with the help of templates. Scott Guthrie has a great introduction to the ListView control here. If you haven't read it, I strongly recommend you do before proceeding.

For this post, we want to fetch 8 records from the database and display it using the ListView control in a tiled format (3 records/row) using the Employee table in the Northwind database. We shall be using a table layout in this example but keep in mind that you can use any html element or control in your markup and the ListView will render it accordingly. In the second part of this post, you will see an example using a pure css layout with div/span tags.

The ListView control allows you to configure 11 templates in your markup. They are shown below:

LayoutTemplate    
  GroupTemplate  
    ItemTemplate
    AlternatingItemTemplate
    SelectedItemTemplate
    EditItemTemplate
    InsertItemTemplate
    EmptyItemTemplate  
    ItemSeparatorTemplate
  GroupSeparatorTemplate  
EmptyDataTemplate    

Note that the SelectedItemTemplate, EditItemTemplate and InsertItemTemplate will not be used in this post. 

LayoutTemplate
The Layout template is where you specify the elements and controls to render at the beginning and end of the ListView. When working in tiled mode, the ListView requires that you include an element/control with id="groupContainer" and the runat="server" attribute in the Layout template. The tag or control marked with this id will be used as a container to instantiate the GroupTemplate

GroupTemplate
The GroupTemplate is where you specify the elements and controls to render the beginning and end of each Group. This template is required when working in tiled mode. The ListView requires that you include an element/control with id="itemContainer" and the runat="server" attribute. This element or control will be used as a container for instantiating the ItemTemplates and AlternatingTemplates.

Note that when working in any other mode (non tiled mode), the GroupTemplate is optional. Also, in non-tiled mode, if you don't have a GroupTemplate defined, you should have an element/control with id="itemContainer" in the LayoutTemplate.  The code snippets below show both cases.

Tiled Mode

 1: <LayoutTemplate>
 2: <table id="groupContainer" runat="server" border="1">
 3: </table>
 4: </LayoutTemplate>
 5: <GroupTemplate>
 6: <tr id="itemContainer" runat="server">
 7: </tr>
 8: </GroupTemplate>

Non Tiled Mode (without GroupTemplate)

 1: <LayoutTemplate>
 2: <table id="itemContainer" runat="server" border="1">
 3: </table>
 4: </LayoutTemplate>

GroupSeparatorTemplate
The elements and controls to render at the end of each GroupTemplate.

ItemTemplate/AlternatingItemTemplate
The elements and controls to render once for each row and alternate row in the result-set data.

EmptyItemTemplate
The EmptyItemTemplate can be used to populate empty columns in a group with the markup defined in the EmptyItemTemplate. In our scenario, we want to fetch 8 records and display them with 3 records in each row. This means that the last row will have one table cell less than the other rows. The ListView will use the markup defined in an EmptyItemTemplate, if present, to fill in missing columns if any.

ItemSeparatorTemplate
The element and controls to render between each ItemTemplate or AlternatingItemTemplate

EmptyDataTemplate
The element and controls to render when the datasource does not contain any records.

I have created a graphic which shows the ListView markup, the rendered html code and what the UI looks like below. I purposefully added some text in each markup to show you the rendered HTML and which template that HTML came from. I reformatted the rendered html by removing the line breaks from the ItemTemplate contents to save vertical space in the graphic (it is still too large though :) 
ListView Web control (RTM)

Note that I have added a GroupItemCount property to the ListView and set its value to 3. This means that each GroupTemplate will instantiate a max of three ItemTemplate + AlternatingItemTemplates.

By looking at the rendered html, we can see that the contents of the LayoutTemplate is used for the outer shell of the ListView. The markup in the GroupTemplate gets added as the inner node of the control with id="groupPlaceHolder". The markup in the ItemTemplate/ItemSeparatorTemplate then gets added as the inner node to the control with id="itemPlaceHolder". After three records are rendered, the contents of the GroupSeparatorTemplate gets added next and the process repeats. We also see that the contents of the EmptyItemTemplate has been added to the empty column in the third row because we had space for 9 records (3 rows x 3 columns) but we fetched only 8 records.

I have full flexibility over how I want the rendered markup to look like. For example, I am not limited to just two tags in the LayoutTemplate; I could have added, for some reason, a Calendar control above the table tag which would get rendered at the start of the ListView. I could also have added some text below the </table> tag causing it to be rendered at the bottom of the ListView. The only requirement is that an element/control with id="groupPlaceHolder" and an element/control with id="itemPlaceHolder" be present somewhere in the LayoutTemplate and GroupTemplate respectively. In addition, these elements/controls should have the runat="server" attribute.

We can further customize the id of the element/control the ListView looks for by declaring the GroupContainerID and ItemContainerID properties. For example, by specifying GroupContainerID="foo", the ListView will look for a element/control with attribute ID="foo" and runat="server" in the LayoutTemplate instead of one with ID="groupPlaceHolder".

On to the coding portion. The ListView is bound to a LinqDataSource. In the selecting event of the LinqDataSource, I have defined a LINQ expression to fetch the first eight records from the Employee table.

The code behind is shown below:

 1: protected void LinqDataSource1_Selecting(object sender, LinqDataSourceSelectEventArgs e)
 2: {
 3: NorthwindDataContext context = new NorthwindDataContext();
 4: var x = (from c in context.Employees
 5: select new { c.EmployeeID, c.LastName }).Take(8);
 6: e.Result = x;
 7: }

Once the page is run, the custom LINQ expression is run, the data fetched and displayed on the page using the layout defined in the ListView control as shown in the graphic above.

I hope this post has given you a taste of what you can do with the ListView in tiled mode. In the next post, we will be looking at how to make an awesome pure CSS layout using the ListView.

2 Comments

  • I REALLY need to see an example of the listview and survey type data or questionaire type display. I am using sqldatasource and am struggling with the new listview formatting. I need something like:
    group header
    &nbsp; one to many questions
    &nbsp; &nbsp; &nbsp; &nbsp;radiobuttongroup control for responses
    repeat...
    Can you help me?
    Thanks,
    Shawn Marie Austin
    web app/database development
    state of WA

  • Is there a way to display the data flow to be vertically in two columns instead of horizontally as you've got it.

    example

    top to bottom in column 1 then
    continue to column 2 top to bottom

Comments have been disabled for this content.