Forms with List Views

Having list views to show a table of records and form views to display, edit, and create individual records is all well and good, but sometimes a single record links to a number of other records in another table and we may want to display these to the user in one place.

Each Site in our corresponding table can have many Buildings assigned to them (but each building can only be assigned to a single site).

In fact each Building can have many Locations assigned to them (and each location is restricted to a single building).

Here we will add to our Site FormView to incorporate a Building ListView that only displays buildings that belong to the selected site.

Access the SiteView.aspx created in the previous tutorial. We will now add to the end of this page to include a sub-table of buildings associated with the given site in the Form View.

Navigate to the end of the document, before the </asp:Content> close tag and just before the last </section> close tag. It will be after the previously created </asp:FormView> close tag.

Start by placing some HTML section containers (we are using Bootstrap CSS classes and the container-row-column hierarchy).

The code below includes a 'Add' button to be coded later so users can create new Building records.

<section class="row">
  <!-- LIST VIEW column -->
    <section class="col-xs-8">
      <h3>Building List</h3>
    </section>
  <section class="col-xs-4 text-right">
    <h3><asp:linkbutton id="btnAddNew" PostBackUrl="~/Restricted/BuildingView.aspx" CommandName="New" runat="server" CssClass="glyphicon glyphicon-plus"/></h3>
  </section>
</section>

<section class="row">
  <section class="col-md-12">

  </section>
</section>

Once you are ready, drag in (or code) an asp:ListView control (found in the toolbox under 'Data').

The image below shows where to insert it.

Rename it appropriately, such as 'LvBuildingList'.

Then, using Microsoft's IntelliSense start typing 'onit...' and select 'OnItemCommand'.

Again using IntelliSense, select to '<Create New Event>' for the property 'OnItemCommand'.

If you use this feature then a subroutine will be automatically generated in the code behind. Typing a subroutine name manually will mean you will have to write the subroutine yourself.

We are almost ready to populate the ListView with template views. Note the close tag '</asp:ListView>' is at the end of this line. You will want to move this a few lines down.

Between the '<asp:ListView>' open and close tags you should establish your templates.

A LayoutTemplate will establish a table with headers using Bootstrap classes 'table' and 'table-hover'. The code for this is shown below.

An 'itemPlaceholder' must be used or you will get an error. This indicates where to place the records to be displayed according to the ItemTemplate.

<LayoutTemplate>
  <table runat="server" id="tblBuildings" class="table table-hover">
    <tr runat="server" >
      <th>Building ID</th>
      <th>Building Name</th>
      <th>Location Count</th>
      <th>View</th>
    </tr>
    <tr runat="server" id="itemPlaceholder" ></tr>
  </table>
</LayoutTemplate>

Immediately following the LayoutTemplate you must now create the ItemTemplate (shown below). This will still be BEFORE the '</asp:ListView>' close tag.

Eval statements are used with the field names provided 

The LocationCount is a calculated field that generated by an adapted 'GetBySiteID' method and is not present in the database itself. 

Ensure you have updated the appropriate method in the BuildingTableAdapter by following the 'SQL Aggregate Functions (Count)' tutorial in the 'Database Connections' series).

<ItemTemplate>
  <tr runat="server">
    <td><asp:Label ID="lblBuildingID" runat="server" Text='<%#Eval("[BuildingID]") %>' /></td>
    <td><asp:Label ID="lblBuildingName" runat="server" Text='<%#Eval("[BuildingName]") %>' /></td>
    <td><asp:Label ID="lblLocationCount" runat="server" Text='<%#Eval("[LocationCount]") %>' /></td>
    <td><asp:LinkButton ID="btnView" runat="server" Text="View" CommandName="View" CommandArgument='<%#Eval("BuildingID") %>'/></td>
  </tr>
</ItemTemplate>

You may like an EmptyDataTemplate to display something when no Buildings are assigned to the Site record.

The code below will show a table with headings and a merged cell in a single row stating "No buildings listed for this site".

The table is copied from the LayoutTemplate with a removal of the CSS class 'table-hover' and the absence of an itemPlaceholder.

<EmptyDataTemplate>
  <table runat="server" id="tblBuildings" class="table">
    <tr runat="server" >
      <th>Building ID</th>
      <th>Building Name</th>
      <th>Location Count</th>
      <th>View</th>
    </tr>
    <tr>
      <td colspan="4" class="text-center">No buildings listed for this site</td>
    </tr>
  </table>
</EmptyDataTemplate>

All our new mark-up is shown below. You can see where the </asp:FormView> closed at the top, and where the section 'container' closes with the </asp:Content> closed tags at the end.

Navigate to the code behind (SiteView.aspx.cs).

To the end of our PageDataRefresh() subroutine (still within the close-brace '}' ) type the following code to bind data to our new ListView.

It will follow similar code for the FormView's data binding (see image below). 

BuildingsTableAdapter buildingsAdapter = new BuildingsTableAdapter();
LvBuildingList.DataSource = buildingsAdapter.GetBySiteID(sID);
LvBuildingList.DataBind();

Locate the automatically generated LvBuildingList_ItemCommand() subroutine that should have been created using IntelliSense when you added an OnItemCommand property to the ListView.

Add the code below to navigate to a BuildingView.aspx web page with query parameters to allow for a particular Building record to be displayed. 

Note the redirected page does not exist yet and you will have to follow the previous 'Form Views' tutorial to create a similar page for Buildings.

Response.Redirect("~/Restricted/BuildingView.aspx?id=" + e.CommandArgument.ToString());

You should now be complete and able to test your additions to the Site FormView. 

As mentioned, viewing Buildings do not lead to a valid page yet so go about repeating the previous tutorial for a Building View, and subsequent Location View web page.

You may then choose to repeat this tutorial to add a list of Locations for each Building.

Well done and good luck expanding this to facilitate Buildings and Locations.