(Data) Bound & Determined
Working with the ListView Control in ASP.NET 3.5
October 30, 2009
LANGUAGES:VB.NET
ASP.NET VERSIONS:3.5
ASP.NET 3.5 introduces a new data-bound control: theListView control. The ListView control was created to add to the capabilitiesof other data-bound controls, such as the Repeater and the DataList controls,and to give you complete control over the HTML markup generated.
The ListView control is a templated data-bound control.This means that ListView requires user-defined templates for its rendering.ListView supports automatic insert, edit, delete, and sort operations, providedits bound data source object supports these capabilities. And the ListViewcontrol also supports paging functionality by using another new control inASP.NET 3.5, the DataPager control. The ListView control provides severaltemplates to control its rendering (see Figure 1).
Template | Description |
---|---|
LayoutTemplate | This is the main container of the control. It can contain group or item placeholders. |
ItemTemplate | This template identifies the layout for each item. |
ItemSeparatorTemplate | Use when you want to define content to be rendered between each item. |
GroupTemplate | Use when you want to group items. You also need to set the GroupItemCount property. |
GroupSeparatorTemplate | Use when you want to define content to be rendered between each group of items. |
EmptyItemTemplate | If you are using the GroupTemplate, you can use this template to define the layout for empty items. |
EmptyDataTemplate | This template identifies content to be rendered when no data is returned from the data source. |
SelectedItemTemplate | Use when you want to differentiate the selected item from the other displayed items. |
AlternatingItemTemplate | Use when you want to distinguish consecutive items. |
EditItemTemplate | Use when you want to add edit functionality. This defines the layout for the item in edit mode. |
InsertItemTemplate | Use when you want to add insert functionality. You also need to set the InsertItemPosition property. |
Figure 1: Theavailable templates in the ListView control.
Creating a Basic Layout
To use the ListView control, you must always define atleast two templates: LayoutTemplate and ItemTemplate.
LayoutTemplate is where you define the root container foryour UI. A root container typically contains one or more HTML containerelements, such as a div, table, or ul element. Somewhere inside LayoutTemplateyou add a placeholder object with its ID set to itemPlaceholder and with therunat= server attribute. (By default, you must use the ID itemPlaceholder,although it s possible to specify a different ID as the reserved identifier foran item placeholder by setting the ItemPlaceholderID property.) Thisplaceholder object will be replaced at run time with the actual content definedfor the item. Also, if you want to edit templates using the designer, you mustmake sure the container controls of the item placeholder object have an ID, aswell. A point that might be potentially confusing is that the placeholder elementcan be anything you like. As noted, it s replaced in its entirety at run time,so it essentially doesn t matter what element you use, as long as it has thecorrect ID and the runat= server attribute. (To avoid confusion and to ensurethe designer will work, it is recommended you use the same element for theplaceholder that you will use for the item template.)
Define the layout of each item inside ItemTemplate. Thiswill contain controls that use a binding expression (the Eval function) toretrieve and display values from the data source. Figure 2 shows the markup fora basic ListView layout using a SqlDataSource object.
Photos
Figure 2: A basicListView layout.
If you compare the ListView control to the Repeatercontrol, you ll notice that the ListView control doesn t contain header andfooter templates, because the LayoutTemplate will contain the main structure asa whole. The markup shown in Figure 2 generates a photo list where each itemrenders an image with a caption. The output produced by this markup is shown inFigure 3.
Figure 3: Output generated by thecode in Figure 2.
Because the ListView control doesn t support styleproperties, you need to style the control inside the templates by using CSSclasses or inline style. But this gives you great control over the layout, andyou can easily hook up existing style sheet files to use with the ListViewcontrol. Note that the markup shown in Figure 2 uses inline style to customizethe rendering for the div, ul, and li elements.
The ListView control also provides some pre-definedlayouts and styles that you can use after you set the data source object. Touse that, open the Design view, then go to the smart tag menu of the controland select Configure ListView.
Adding Sort, Select, Update, Delete, and Insert Capabilities
The ListView control supports some operationsautomatically, provided its bound data source object also supports them. If thedata source does not support the behavior you want, you can implement it byhandling a ListView control event.
You need to add buttons to perform update, delete, insert,select, and sort operations automatically, and they need to be placed in theappropriate template. (This is similar to how you work with the other templateddata-bound controls.) The ListView control recognizes the operation requestedbased on the CommandName property of the button. Figure 4 shows the list ofrecognized values and their function.
Value | Function |
---|---|
Cancel | Cancels an edit or insert operation. Used in the InsertItemTemplate or EditItemTemplate templates. |
Delete | Deletes the item from the data source. |
Edit | Puts the item in edit mode and renders the EditItemTemplate for the item. |
Insert | Inserts the bound values into the data source. Used in the InsertItemTemplate. |
Select | Selects the item and renders the SelectedItemTemplate for the selected record. |
Sort | Sorts the columns listed in the CommandArgument property of the button. |
Update | Updates records in the data source. Used in the EditItemTemplate. |
Figure 4: A listof the recognized CommandName property values.
You can also provide a custom value for the CommandNameproperty. In this case, there is no action as a default behavior. But you cancreate an event-handling method for the ItemCommand event and add functionalitythere for your custom action.
Sorting and Selecting an Item
Figure 5 shows the markup for a ListView control thatshows data from a table that contains two columns: LastName and FirstName. InLayoutTemplate, a header row was added and each header cell is a LinkButtoncontrol that enables users to sort by the corresponding field. The buttonsCommandName property is set to Sort, so the ListView control performs sortingand you don t have to write any code to handle this task. This markup alsoshows how to select an item by adding a button to the ItemTemplate. Using thesame technique, the button s CommandName property is set to Selectto select the item.
<%#Eval("LastName")%> <%#Eval("FirstName")%> &nsbp; <%#Eval("LastName")%> <%#Eval("FirstName")%>
Figure 5: AListView control with sort and select functionality.
Inserting, Updating, and Deleting
To enable insert, update, and delete operations in theListView control, you must set the primary keys of the table in theDataKeyNames property. (If you use the Configure Data Source smart-tag commandon the designer to set up data binding, this might be done automatically foryou.) For the insert or edit operations only, you must also define theInsertItemTemplate and EditItemTemplate templates. The controls inside the templatescan be created using two-way binding expressions with the Bind function (forcontrols that will be used to modify or create values). This way, the valuesare automatically passed to the data source object. For the insert operation,you also need to set the InsertItemPosition property of the ListView control toa value different than None so the template can bedisplayed. If you set the property to FirstItem, the ListView control rendersthe insert template before all data items; if you set it to LastItem, thecontrol renders the insert template in the end of the page.
Figure 6 shows an example of a ListView control that usesthe same database table as Figure 5, but the control has the update, insert,and delete operations enabled. Four templates are defined in the markup:LayoutTemplate, ItemTemplate, EditItemTemplate, and InsertItemTemplate. Theinsert template is displayed at the bottom of the ListView control because theInsertItemPosition is set to LastItem.
Figure 6: AListView control that has insert, edit, and delete operations.
It is important to notice that the trelement from InsertItemTemplate and EditItemTemplate doesn t contain the runat= serverattribute. This will break the design-time experience; however, it is necessarywhen you are using tr or td elements as placeholdersfor the templates that use two-way data binding expressions at run time. If youleave the runat attribute, it can result in data loss at run time. The markupshown in Figure 6 generates a table where each row shows a record. The outputproduced by this markup is shown in Figure 7.
Figure 7: Output generated by thecode in Figure 6.
Adding Paging Functionality
The ListView control doesn t have a built-in pagingfeature, but you can easily add paging functionality by adding a DataPagercontrol to your page or inside the LayoutTemplate of the ListView control. Itprovides paging for any control that implements the IPageableItemContainerinterface. So far, the only control that implements this interface is theListView control.
The DataPager control lets you use a combination of pre-definedpager fields. It provides the NextPreviousPagerField object that containsFirst/Next/Previous/Last buttons (which you can selectively remove) and theNumericPagerField object that enables you to navigate using the page numbers.The DataPager control also has the TemplatePagerField field type that enablesyou to create a customized UI. By setting the PageSize property in theDataPager control, you determine the number of records that are displayed perpage.
Figure 8 shows an example of a ListView control that usesan XmlDataSource control that reads the entries from an RSS feed, and containsa DataPager control inside the LayoutTemplate to add paging functionality. Thisexample also adds an AlternatingItemTemplate to the ListView control todistinguish one row from another.
<%#Convert.ToDateTime(XPath("pubDate")).ToShortDateString()%> <%#Convert.ToDateTime(XPath("pubDate")).ToShortDateString()%>
Figure 8: AListView control that has paging functionality.
Using the markup shown in Figure 8 lets you create a pagerthat shows a First Page button, the page numbers, and a Last Page button. Ifyou place the DataPager control outside the ListView control, you also need toset the PagedControlID property so the pager knows what data to page.
Creating Groups of Items
The ListView control includes the GroupTemplate templatewhich you won t find in the other data controls. The GroupTemplate enables youto repeat a certain content for a specified number ofitems. In other words, this template enables you to display items in groupstable rows, individual div elements, or whatever other grouping you want. Specifyhow many items are in each group, then create a layoutnot only for the items, but for the group as a whole.
The number of items displayed for each group is defined bythe GroupItemCount property. The most common application of this template iswhen you want to create a tiled table layout.
For grouping the items, add a group placeholder object tothe LayoutTemplate instead of an item placeholder. To do this, add aplaceholder object with its ID set to groupPlaceholder and with the runat= serverattribute. This placeholder object will be replaced at run time with the actualcontent defined for the group.
Then, inside the GroupTemplate, define the grouping layoutand your item placeholder object. Add the item placeholder object with its IDset to itemPlaceholder and with the runat= server attribute. This placeholderobject will be replaced at run time with the actual content defined for theitem.
When you group items, it is useful to define content foranother template, the EmptyItemItemplate. This template will be rendered whenthere are no more items to display in a page.
Figure 9 shows an example of a ListView control using thegrouping feature. This ListView control is using a new data source object inASP.NET 3.5, the LinqDataSource control. A LINQ to SQL data model was createdfor the Employees table to be able to use the LinqDataSource control.
Employees
Figure 9: AListView control with a tiled table layout that is created by grouping.
As you can see in the markup shown in Figure 9, both IDvalues used for the placeholder objects (itemPlaceholder and groupPlaceholder)can be changed by using the ItemPlaceholderID and GroupPlaceholderIDproperties. Again, if you want to edit templates using the designer, you mustensure the container controls of the placeholder objects have an ID, as well.
The markup shown in Figure 9 generates a table with tworecords per row. The last row has an empty item, because in the example dataset, there is an odd number of records. The outputproduced by this markup is shown in Figure 10.
Figure 10: Output generated by thecode in Figure 9.
LINQ is a new set of extensions in the .NET Framework 3.5that encompass language-integrated data query, set, and transform operations.You can use LINQ queries or other objects (such as DataSet objects) instead ofa data source control to bind data to the ListView control. Figure 11 shows thecode to replace the LinqDataSource control used in Figure 9 with a LINQ query.You can keep the same markup for the templates.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Dim dataContext As New NorthwindDataContextDim countryName As String = Request.QueryString("Country") Dim employees = From f In dataContext.Employees _ Where f.Country = countryName EmployeesListView.DataSource = employees EmployeesListView.DataBind()End Sub
Figure 11: Bindingthe ListView control to a LINQ query.
The disadvantage of using the DataSource property insteadof binding the control to a data source object is that this approach requiresthat you write code for any additional functionality, such as sorting, paging, deleting,and updating. In this case, you must add event handlers for the appropriateevents.
Using Events
The ListView control provides many events for you to addfunctionality to your control or provide additional logic in response to theevent. Figure 12 lists the main events that are provided by the ListViewcontrol.
Event | Description |
---|---|
DataBinding/DataBound | Occurs when/after the ListView control binds to a data source. |
ItemCanceling | Occurs when a cancel operation is requested, but before the insert or edit operation is cancelled. |
ItemCommand | Occurs when a button is clicked. |
ItemCreated | Occurs when an item is created. |
ItemDataBound | Occurs when a data item is bound to data. |
ItemDeleting/ItemDeleted | Occurs when a delete operation is requested, but before/after the item is deleted. |
ItemEditing | Occurs when an edit operation is requested, but before the item is put in edit mode. |
ItemInserting/ItemInserted | Occurs when an insert operation is requested, but before/after the item is inserted into the data source. |
ItemUpdating/ItemUpdated | Occurs when an update operation is requested, but before/after the item is updated in the data source. |
LayoutCreated | Occurs when the LayoutTemplate template is created. |
PagePropertiesChanging/PagePropertiesChanged | Occurs when the page properties change, before/after the control sets the new values. |
SelectedIndexChanging/SelectedIndexChanged | Occurs when a select operation is requested, before/after the select operation is handled. |
Sorting/Sorted | Occurs when a sort operation is requested, before/after the sort operation is handled. |
Figure 12: Mainevents provided by the ListView control.
Figure 13 shows an example of a ListView control thatconsumes the ItemDataBound event; Figure 14 shows the code for theItemDataBound event-handling method. The event-handling method accesses one of thecontrols inside the data item to verify if the stock is low. If the stock islow, the font color is changed to distinguish from the records that have aregular number of items in stock.
Figure 13: AListView control that consumes the ItemDataBound event.
Protected Sub ListView1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewItemEventArgs) 'Obtain the item Dim UnitsLabel As Label = CType(e.Item.FindControl("UnitsInStockLabel"), Label) If (UnitsLabel.Text.Length > 0) Then 'Check if the stock is low Dim units As Int16 = CType(UnitsLabel.Text, Int16) If (units < 15) Then 'Display the value in red when the stock is low UnitsLabel.ForeColor = Drawing.Color.Red End If End IfEnd Sub
Figure 14: Theevent-handling method for the ItemDataBound event.
Conclusion
The ListView control might not be as innovative as othernew features in the .NET Framework 3.5 such as LINQ or AJAX but it s agreat data-bound control for you to use when you need complete control over thegenerated HTML markup or when you need all the common data operations combinedin one single control.
The filesaccompanying this article are available for download.
Maira Wenzel, MCSD,is a Programming Writer in the ASP.NET User Education team. She has beenextensively working with Microsoft technologies since 2000, including SQLServer, ASP.NET, C#, Visual Basic, and SharePoint Server.
About the Author
You May Also Like