Using ASP.NET 3.5's ListView and DataPager Controls: Editing Data
By Scott Mitchell
| A Multipart Series on ASP.NET's ListView and DataPager Controls |
|---|
|
This article is one in a series of articles on ASP.NET's ListView and DataPager controls, which were introduced with ASP.NET version 3.5.
|
Introduction
The GridView and DetailsView controls offer built-in editing functionality that can be turned on with the tick of a checkbox. Without writing a line of declarative markup or server-side source code, the page developer gets a decent out of the box editing interface. Namely, each field in the GridView or DetailsView is rendered in its editing interface; BoundFields display a TextBox control while CheckBoxFields display an enabled checkbox. Moreover, a CommandField is added, which displays the Edit, Update, and Cancel buttons, as needed.
While the ListView control provides editing support, it requires a bit more work from the page developer to get it going. The reason is because the ListView is defined by
templates whereas the GridView and DetailsView are defined by fields. Many fields types, such as the BoundField, can generate their own editing interface, but with templates
the page developer is on the hook for specifying the editing interface. Creating an editable ListView control entails defining the editing interface via the
EditItemTemplate and adding the Edit, Update, and Cancel buttons in the appropriate spots.
This article walks through creating an editable ListView control, with the finished results available for download at the end of the article. Read on to learn more!
(It is assumed that the reader is familiar with how to edit data using a data source control. If this is not the case, please first read Accessing and Updating Data in ASP.NET: Updating Basics.)
An Overview of the ListView's Editing Workflow
A ListView control that supports editing typically includes an Edit button with each item that, when clicked, displays that item's editing interface. The editing interface includes Web controls for editing the item's data - TextBoxes, DropDownLists, CheckBoxes, and so on - along with Update and Cancel buttons. Clicking the Cancel button returns the item to its pre-editing, read-only state whereas clicking the Update button saves the user's modifications in the database (or wherever) and then returns the item to its read-only state, showing its newly updated values. The screen shot below shows a ListView control that lists the products from the Northwind database table. Note that all of the read-only items have an Edit button. However, the product Aniseed Syrup has had its Edit button clicked and is rendered in its edit mode. The editing interface displays TextBoxes and DropDownList controls for the various fields and has Update and Cancel buttons instead of the Edit button.
Whenever one of the Edit buttons is clicked a postback ensues and the ListView begins its editing workflow. (In the screen shot above the "Edit button" is the pencil icon and is implemented as an ImageButton.) This workflow proceeds as follows:
- The ListView raises its
ItemEditingevent. - The ListView sets its
EditIndexproperty to the index of the row whose Edit button was clicked. - The ListView rebinds to its data source.
- The row whose index corresponds to the
EditIndexvalue has itsEditItemTemplaterendered (instead of itsItemTemplate)
- The ListView raises its
ItemCancelingevent. - The ListView sets its
EditIndexproperty to -1. - The ListView rebinds to its data source.
- All rows are displayed in their read-only mode (because no row has an index of -1).
- The ListView raises its
ItemUpdatingevent. - The ListView assigns the values supplied in the editing interface to the update parameters for its associated data source control.
- The ListView assigns the key values for the row being updated to the update parameters for its associated data source control.
- The ListView calls its associated data source control's
Updatemethod, which actually performs the update. - The ListView raises its
ItemUpdatedevent handler. - The ListView sets its
EditIndexproperty to -1. - The ListView rebinds to its data source.
EditIndex has been set to -1. Furthermore, the
just-updated record's new values are displayed in the read-only interface because the data is rebound to the ListView (step 7) after the update is issued (step 4).
From the end user's perspective, the end-to-end data modification workflow unfolds like this: the user clicks the Edit button; there's a short pause before that item's editing interface is displayed. The user modifies the data as needed and clicks the Update button, which saves the data and returns the screen to its pre-editing view.
Implementing the Read-Only Interface (ItemTemplate)
Adding updating support to the ListView requires that the ListView's underlying data source control support updating. That means that if you are using a SqlDataSource or AccessDataSource control as the ListView's data source that the SqlDataSource (or AccessDataSource) must have an
UpdateCommand specified. If you are using an
ObjectDataSource then you will need to have specified what object method to invoke to perform the update. For more background on configuring the data source controls to support
updating, refer to Accessing and Updating Data in ASP.NET: Updating Basics.
Recall that in order to display the editing interface there needs to be some Button control in the ItemTemplate that serves as the Edit button. This button can
be any type of Button control (a regular Button, a LinkButton, or an ImageButton), but it must have its CommandName property set to "Edit". The demo available
for download at the end of this article includes a ListView that displays records from the Northwind database's Products table. The markup for the ItemTemplate
displays each product's ProductName field in an <h3> element as well as the product's supplier, category, and unit price. There's
also an ImageButton control (the pencil icon) that serves as the Edit Button. Note that its CommandName property is set to "Edit".
<asp:ListView ID="lvProducts" runat="server" DataSourceID="dsNorthwind" DataKeyNames="ProductID">
|
Along with adding an Edit button, it's also equally important that the ListView's DataKeyNames property be set to the column(s) that comprise the primary key.
The Products table's primary key is ProductID. Therefore, in order for this ListView to correctly implement deleting it is imperative that its
DataKeyNames property be set to ProductID, as it is in the markup above. If this property is not set then the updating workflow will not work.
Any changes made to the editing interface will not be saved back to the database.
Implementing the Editing Interface (EditItemTemplate)
The editing interface is defined via the ListView control's
EditItemTemplate. This template must contain the data entry Web controls to collect the necessary
inputs, along with Edit and Cancel buttons. What input needs to be collected depends on the data source control's update logic. For example, if you are using a SqlDataSource
control that has an UpdateCommand statement like:
UPDATE Products SET
|
Then you would need two input controls in the EditItemTemplate: one for ProductName and one for UnitPrice. (The value for the
primary key field ProductID is retrieved via the ListView's DataKeys collection, which is why it is essential that you set the ListView's
DataKeyNames property to the primary key column.)
When the EditItemTemplate is first rendered the input Web controls need to show the current values of the item being edited. Then, when the user clicks the
Update button, the user's inputs need to be sent off to the data source control. This can be accomplished without writing any code by using two-way data binding. Two-way
data binding is implemented by using the syntax <%# Bind("columnName") %> on the input Web control's appropriate property. For TextBox controls you'd
use the Bind syntax on the Text property; for DropDownLists you'd use it on the SelectedValue property. The following markup,
from the ListView's EditItemTemplate, shows this two-way databinding syntax in action with two TextBoxes for the ProductName and UnitPrice fields
and two DropDownLists for the CategoryID and SupplierID fields:
<asp:ListView ID="lvProducts" runat="server" DataSourceID="dsNorthwind" DataKeyNames="ProductID">
|
In addition to the TextBox and DropDownList controls, the EditItemTemplate also contains the Update and Cancel buttons. As with the Edit button, these can be implemented as
Button, LinkButton, or ImageButton controls. What is key is that their CommandName properties be set to "Update" and "Cancel".
Also note that you can add validation controls to the EditItemTemplate to ensure that the user's inputs are valid. In the example above I added a RequiredFieldValidator
for the txtProductName TextBox because ProductName is a required field in the database. I also added a CompareValidator for the txtUnitPrice
TextBox to ensure that the user enters a valid currency value greater than or equal to zero.
Finally, examine the DropDownLists. Note that I've set the AppendDataBoundItems to True and added a static ListItem with an empty string as the
Value and the Text "None / Unknown". This handles the NULL case. The Products table allows for NULL values for
its CategoryID and SupplierID columns. To correctly display the editing interface for a product that has a NULL value for one of these columns and
to allow the user to set a product's CategoryID or SupplierID value to NULL we need to use the above approach. See
Accessing and Updating Data in ASP.NET 2.0: Handling Database NULL Values for more information on this
topic.
| What If I'm Not Using a Data Source Control? |
|---|
The ListView control can be bound to data via a data source control or by programmatically settings its DataSource property and calling its DataBind
method. If you use this latter approach then you cannot take advantage of the automatic updating capabilities of the data source control. Instead, you will need to create
an event handler for the ListView's ItemUpdating event and implement your own updating logic there.
|
Short-Circuiting the Updating Workflow
In some scenarios you may want to cancel the updating workflow based on the user's input or some other type of programmatic logic. Perhaps any user can increase the price of a product but only certain users can decrease the price. Or maybe you want to parse the user's input for the
ProductName field and prohibit the update if there
are any curse words in the product name.
Whatever the rationale may be, you have an opportunity to examine both the original values and the user's edits before the update is committed via the ItemUpdating event
handler. The demo available at the end of this article includes such an event handler that checks to see if the ProductName value entered by the user contains
more than three words. If such a lengthy product name is found then the update is canceled and the user is shown a message explaining the issue.
The code for the ItemUpdating event handler is straightforward. It pulls the value entered into the ProductName field via the e.NewValues collection.
It then splits on spaces (" "). If there are more than two spaces in the product name then, presumably, there are more than three words, so the update is canceled by setting
e.Cancel to True and a message is displayed via the DisplayAlert method, which is defined in a custom base Page class.
Protected Sub lvProducts_ItemUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewUpdateEventArgs) Handles lvProducts.ItemUpdating
|
The following screen shot shows the client-side messagebox that is displayed when the user attempts to enter a product name that's more than three words (such as "Aniseed Syrup Is Good!")
Conclusion
The ListView control provides inserting, updating, and deleting functionality. As we saw in this installment, adding editing capabilities to the ListView is relatively straightforward: add an Edit button to the
ItemTemplate, define the editing interface via the EditItemTemplate, and add Update and Cancel buttons to the
EditItemTemplate. That's it! The data source control handles the actual updating of data.
The next installment shows how to insert data through the ListView control.
Happy Programming!
Further Readings:
Attachments




