The Listview control introduced in ASP.NET 3.5 fixes a number of issues with the old Gridview and Repeater controls. In particular, one of my biggest problems with the Gridview was the inability to add an item through an empty row in the Gridview footer. While there are several workarounds to achieve this functionality, the Listview makes it nice and easy. This article demonstrates how.
Demo | Code
Step 1 - Create a Listview
Create a simple listview with a LayoutTemplate and ItemTemplate to display your data. Here is some sample code you can use:
<asp:ListView ID="Listview2" runat="server" DataKeyNames="ID"
DataSourceID="dsListView" InsertItemPosition="LastItem">
<LayoutTemplate>
<table cellpadding="0" cellspacing="0" class="ListviewTable" width="540">
<tr>
<th style="width: 40px">
ID
</th>
<th style="width: 110px">
First Name
</th>
<th style="width: 110px">
Last Name
</th>
<th style="width: 120px">
Department
</th>
<th style="width: 120px">
Location
</th>
<th style="width: 40px">
</th>
</tr>
<tr id="itemPlaceholder" runat="server" />
<tr>
<td colspan="5" align="center">
Page:
<asp:DataPager ID="DataPager1" runat="server" PageSize="12">
<Fields>
<asp:NumericPagerField ButtonCount="5" />
</Fields>
</asp:DataPager>
</td>
</tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td>
<%#Eval("ID")%>
</td>
<td>
<%#Eval("FirstName")%>
</td>
<td>
<%#Eval("LastName")%>
</td>
<td>
<%#Eval("Location")%>
</td>
<td>
<%#Eval("Department")%>
</td>
<td>
</td>
</tr>
</ItemTemplate>
</asp:ListView>
In the Listview control you'll see InsertItemPosition="LastItem" which puts the insert item template into the Listview's footer. You can use FirstItem to show the insert item template at the top of your data.
Step 2 - Create the SQL Data Source
My usual disclaimer here - I don't recommend using SQL Data Sources in a production environment, I instead prefer to seperate the data access layer and use Object Data sources. However, for the purposes of this demo, the SQKDataSource is a lot easier to demonstrate.
Make sure you include an InsertCommand and InsertParameters as shown below:
<asp:SqlDataSource ID="dsListview" ConnectionString="<%$ ConnectionStrings:MyConnection %>"
runat="server" SelectCommand="SELECT * FROM [T_Employees]"
InsertCommand="Insert into T_Employees (firstname, lastname, location, department)
values (@firstname, @lastname, @location, @department)">
<InsertParameters>
<asp:Parameter Name="FirstName" Type="String" />
<asp:Parameter Name="LastName" Type="String" />
<asp:Parameter Name="Location" Type="String" />
<asp:Parameter Name="Department" Type="String" />
</InsertParameters>
</asp:SqlDataSource>
Step 3 - Add the InsertItemTemplate
Finally, add an InsertDataTemplate which contains bound controls for your InsertParameters. I've also included validators here and a validation summary, to ensure that proper data is being entered into the database:
<InsertItemTemplate>
<tr>
<td>
</td>
<td>
<asp:TextBox ID="txtFirstName" runat="server" Width="80px"
Text='<%#Bind("FirstName")%>' />
<asp:RequiredFieldValidator ID="RV1" ControlToValidate="txtFirstName"
runat="server" ErrorMessage="First Name is required." Display="Dynamic"
ValidationGroup="InsertFields">*</asp:RequiredFieldValidator>
</td>
<td>
<asp:TextBox ID="txtLastName" runat="server" Width="80px"
Text='<%#Bind("LastName")%>' />
<asp:RequiredFieldValidator ID="RV2" ControlToValidate="txtLastName"
runat="server" ErrorMessage="Last Name is required." Display="Dynamic"
ValidationGroup="InsertFields">*</asp:RequiredFieldValidator>
</td>
<td>
<asp:TextBox ID="txtLocation" runat="server" Width="90px"
Text='<%#Bind("Location")%>' />
<asp:RequiredFieldValidator ID="RV3" ControlToValidate="txtLocation"
runat="server" ErrorMessage="Location is required." Display="Dynamic"
ValidationGroup="InsertFields">*</asp:RequiredFieldValidator>
</td>
<td>
<asp:TextBox ID="txtDepartment" runat="server" Width="90px"
Text='<%#Bind("Department")%>' />
<asp:RequiredFieldValidator ID="RV4" ControlToValidate="txtDepartment"
runat="server" ErrorMessage="Department is required." Display="Dynamic"
ValidationGroup="InsertFields">*</asp:RequiredFieldValidator>
</td>
<td>
<asp:LinkButton ID="LinkButton1" CommandName="Insert" Text="Add"
runat="server" CausesValidation="true" ValidationGroup="InsertFields" />
</td>
</tr>
<asp:ValidationSummary ID="ValidationSummary1" runat="server" ShowMessageBox="true"
ShowSummary="false" ValidationGroup="InsertFields" />
</InsertItemTemplate>
That's it! You now have text boxes in your Listview's footer that allow your users to insert items into your database. If you want to make the user press a button to display the Insert Item template, then in your Listview, set InsertItemPosition="None." Then, create an 'Add' button and in your code behind type 'Listview1.InsertItemPosition = InsertItemPosition.FirstItem'. After the insert you can then set 'Listview1.InsertItemPosition = InsertItemPosition.None' (Put this in your Listview1_ItemInserted Sub).
As usual, check out the demo or download the source code.
Good luck,
Bartek