Monday 12 August 2013




The asp:ListView control supports data editing, insertion, deleting, paging and sorting like another powerful asp.net control GridView.  But - unlike the GridView, it provides us with complete control over the html markup generated like DataList or Repeater control using templates and styles.
Base Code of the ListView for this Article
Following is the code of the ListView for this article, based on this I am going to explain most freqently asked questions about ListView Control. If you are learning asp:ListView control while reading this article, you may copy-paste code described here. I have also provided downloadable code, please feel free to download and use it.
Code - 1
<form id="form1" runat="server">
<div>
<h3>Data Manipulation, Sorting, Paging using ListView Control</h3>
<hr />
<asp:Label ID="lblMessage" runat="server" EnableViewState="false" ForeColor="Blue"></asp:Label>
<asp:ListView ID="ListView1" runat="server" ItemPlaceholderID="PlaceHolder1" OnItemEditing="EditListViewItem"
OnItemCanceling="CancelListViewItem" OnItemUpdating="UpdateListViewItem" DataKeyNames="AutoId"
OnPagePropertiesChanging="PagePropertiesChanging" OnItemInserting="InsertListViewItem"
InsertItemPosition="LastItem" OnItemDeleting="DeleteListViewItem" OnSorting="SortListViewRecords">
<LayoutTemplate>
<table width="100%" cellpadding="4" cellspacing="0">
<tr class="header">
<th style="width: 30%;">
<asp:LinkButton ID="lnkSort1" runat="server" CommandName="Sort" CommandArgument="Name" Text="Name" />
</th>
<th style="width: 50%;">
<asp:LinkButton ID="LinkButton1" runat="server" CommandName="Sort" CommandArgument="Address" Text="Address" />
</th>
<th style="width: 20;">
<asp:LinkButton ID="LinkButton2" runat="server" CommandName="Sort" CommandArgument="Phone" Text="Phone" />
</th>
<th>
Modify</th>
</tr>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr class="item">
<td>
<%# Eval("Name") %>
</td>
<td>
<%# Eval("Address") %>
</td>
<td>
<%# Eval("Phone") %>
</td>
<td>
<asp:LinkButton ID="lnkEdit" runat="server" Text="Edit" CommandName="Edit" />
<span onclick="return confirm('Are you sure to delete?')">
<asp:LinkButton ID="lnkDelete" runat="server" Text="Delete" CommandName="Delete" ForeColor="Brown"/>
</span>
</td>
</tr>
</ItemTemplate>
<AlternatingItemTemplate>
<tr>
<td>
<%# Eval("Name") %>
</td>
<td>
<%# Eval("Address") %>
</td>
<td>
<%# Eval("Phone") %>
</td>
<td>
<asp:LinkButton ID="lnkEdit" runat="server" Text="Edit" CommandName="Edit" />
<span onclick="return confirm('Are you sure to delete?')">
<asp:LinkButton ID="lnkDelete" runat="server" Text="Delete" CommandName="Delete" ForeColor="Brown" />
</span>
</td>
</tr>
</AlternatingItemTemplate>
<EditItemTemplate>
<tr class="edititem">
<td>
Name:<asp:TextBox ID="txtName" runat="server" Text='<%# Eval("Name") %>' />
</td>
<td>
Address:<asp:TextBox ID="txtAddress" runat="server" Text='<%# Eval("Address") %>' />
</td>
<td>
Phone:<asp:TextBox ID="txtPhone" runat="server" Text='<%# Eval("Phone") %>' />
</td>
<td>
<span onclick="return confirm('Are you sure to update?')">
<asp:LinkButton ID="btnUpdate" runat="server" Text="Update" CommandName="Update" />
</span>
<asp:LinkButton ID="btnCancel" runat="server" Text="Cancel" CommandName="Cancel" />
</td>
</tr>
</EditItemTemplate>
<InsertItemTemplate>
<tr class="insert">
<td>
Name:<asp:TextBox ID="txtName" runat="server" Text='<%# Eval("Name") %>' />
</td>
<td>
Address:<asp:TextBox ID="txtAddress" runat="server" Text='<%# Eval("Address") %>' />
</td>
<td>
Phone:<asp:TextBox ID="txtPhone" runat="server" Text='<%# Eval("Phone") %>' />
</td>
<td>
<span onclick="return confirm('Are you sure to insert?')">
<asp:LinkButton ID="btnInsert" runat="server" Text="Insert" CommandName="Insert" />
</span>

</td></tr>
</InsertItemTemplate>


</asp:ListView><div style="text-align: center; font-weight: bold;">
<asp:DataPager ID="DataPager1" runat="server" PagedControlID="ListView1" PageSize="5">
<Fields>
<asp:NumericPagerField ButtonCount="5" />
</Fields>
</asp:DataPager>
</div>
</div>
</form>
Above code will bring the ListView look like following provided you have same records as mind :), Just to look it better, I have used some css, you can find complete code including database in the download above.
Picture - 1
To demonstrate solution of frequently asked questions in ListView, I have created a small database having a table named Details. It has Name, Address, Phone fields. Throughout this article, I will use the same table.
Throughout this article, I have written all code into code behind file, in real scenario you should use layerd or tiered architecture and write stored procedure to interact with the database.
Tip 1 - Binding ListView
To Bind the data in ListView control, you need to do following:
  1. Cerate LayoutTemplate (In my case I have used Table, so I have all the header of the column there and a PlaceHolder control.
  2. Attach the PlaceHolder with the ListView by specifying ItemPlaceHolderID of the ListView
  3. Create ItemTemplate (and/or AlternatingItemTemplate)
  4. As I want to Edit and Delete the data using ListView control so I have a separte column called modify having two link buttons Edit and Delete
  5. Write method to get the data from database and bind it. (In my case I have opened a database connection, executed the select query and get the Data into DataTable and bind it. My code looks like following.)
Code - 2
/// <summary>
/// Bind Person Details data
/// </summary>
private void BindPersonDetails(string sortExpression)
{
sortExpression = sortExpression.Replace("Ascending", "ASC");
using (SqlConnection conn = new SqlConnection(_connStr))
{
conn.Open();
using (SqlDataAdapter dAd = new SqlDataAdapter("select * from Details order by Name", conn))
{
DataTable dTable = new DataTable();
dAd.Fill(dTable);
// Sort now
dTable.DefaultView.Sort = sortExpression;// Bind data now
ListView1.DataSource = dTable;
ListView1.DataBind();
}
conn.Close();
}
}
You can notice that I am passing a parameter in this method called sortExpression. After getting records into DataTable, I am sorting it based on the sortexpression passed to this method. This will help me in implementing Sorting functionality in ListView control.
Tip 2 - Adding records in ListView
To add records using ListView control, you need to add InsertItemTemplate inside GridView (Code - 1). In this template I have created a link button called Insert and specified CommandName as Insert. This allows ListView control to fire OnItemInserting event. Once you have added the InsertItemTemplate, you need to specify a method for OnItemInserting event handler. My method name is InsertListViewItem and my code looks like following:
Code - 3
/// <summary>
/// Fires when Insert button is clicked
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void InsertListViewItem(object sender, ListViewInsertEventArgs e)
{
ListViewItem item = e.Item;
TextBox tName = (TextBox) item.FindControl("txtName");
TextBox tAddress = (TextBox)item.FindControl("txtAddress");
TextBox tPhone = (TextBox)item.FindControl("txtPhone");
// insert records into database
using (SqlConnection conn = new SqlConnection(_connStr))
{
string Sql = "insert into Details (Name, Address, Phone) values " +
" (@Name, @Address, @Phone)";
conn.Open();
using (SqlCommand dCmd = new SqlCommand(Sql, conn))
{
dCmd.Parameters.AddWithValue("@Name", tName.Text.Trim());
dCmd.Parameters.AddWithValue("@Address", tAddress.Text.Trim());
dCmd.Parameters.AddWithValue("@Phone", tPhone.Text.Trim());
dCmd.ExecuteNonQuery();
}
conn.Close();

}
lblMessage.Text = "New Records Inserted Successfully.";
// Rebind the details
BindPersonDetails("Name ASC");
}
As soon as you will fill the TextBoxes for Name, Address, and Phone and click Insert button, InsertListViewItem method will fire. In this method, first I am getting the item of the ListView. Using item.FindControl, I got the TextBoxes for Name, Address and Phone inside InsertItemTemplate. Next, I have written code to open a database connection and executed insert query after setting the value of the required parameter. Once i am done with executing the query, I have Rebound (Code - 2) the ListView control.
Tip 3 - Editing records in ListView
To Edit records in ListView control, we need to add EditItemTemplate (Code - 1). Clicking Edit link in the default mode for respective record bring that record into Edit mode so that user can modify the record. Once Edit link will be clicked then OnItemEditing event of the ListView will fire. In this method, I have specifiedEditListViewItem method and my code for this method looks like following:
/// <summary>
/// Fires when Edit link is clicked
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void EditListViewItem(object sender, ListViewEditEventArgs e)
{
ListView1.EditIndex = e.NewEditIndex;
// Rebind the details
BindPersonDetails("Name ASC");
}
In this method, I have specified the EditIndex peroperty of the ListView as the NewEditIndex (the clicked reocrd) and rebind the ListView so that I will have current record data into the Edit mode.
Tip 4 - Updating records in ListView 
Notice that in the EditItemTemplate I have two link buttons called Update and Cancel having CommandName as Update and Cancel respectively. Clicking Update and Cancel buttons will fire OnItemUpdating and OnItemCanceling event respectively. I have attached UpdateListViewItem and CancelListViewItem methods for Updating and Canceling records.
Updating Records
Code - 4
/// <summary>
/// Fires when Update link is clicked
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void UpdateListViewItem(object sender, ListViewUpdateEventArgs e)
{
ListViewItem item = ListView1.Items[e.ItemIndex];

int autoID = int.Parse(ListView1.DataKeys[e.ItemIndex].Value.ToString());
TextBox tName = (TextBox)item.FindControl("txtName");
TextBox tAddress = (TextBox)item.FindControl("txtAddress");
TextBox tPhone = (TextBox)item.FindControl("txtPhone");
// insert records into database
using (SqlConnection conn = new SqlConnection(_connStr))
{
string Sql = "update Details set Name = @Name, Address = @Address, Phone = @Phone where AutoID = @AutoID";
conn.Open();
using (SqlCommand dCmd = new SqlCommand(Sql, conn))
{
dCmd.Parameters.AddWithValue("@AutoID", autoID);
dCmd.Parameters.AddWithValue("@Name", tName.Text.Trim());
dCmd.Parameters.AddWithValue("@Address", tAddress.Text.Trim());
dCmd.Parameters.AddWithValue("@Phone", tPhone.Text.Trim());
dCmd.ExecuteNonQuery();
}
conn.Close();
lblMessage.Text = "Records Updated Successfully.";
}
ListView1.EditIndex = -1;
// Rebind the details
BindPersonDetails("Name ASC");
}
Above method will fires when user clicks Update link. In this method, I have the item to be edited using ListView.Items[e.ItemIndex] and got the key value (In Code - 1, I have specified DataKeyName=AutoID).  I got the TextBoxes in the Edit mode using item.FindControl andr est code is as usual, simply opening the connection and executing the update statement. Once I am done I have rebound the ListView to ensure that my list after modifying records is updated.
Cancelling Update
When Cancel link button will be clicked then Edit mode of the ListItem should be cancelled and ListView should be displayed in Default mode. To do that write following code.
/// <summary>
/// Fires when Cancel link is clicked
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void CancelListViewItem(object sender, ListViewCancelEventArgs e)
{
ListView1.EditIndex = -1;
// Rebind the data
BindPersonDetails("Name ASC");
}
In the above method, I have specied EditIndex property of the ListView as -1 (instructing that I don't want to edit any item) and rebinding the records. This will bring the ListView in its default mode (Picture - 1).

Tip 5 - Deleting records in ListView
Notice that I have a Delete link in the ItemTemplate and AlternatingItemTemplate with CommandName as Delete. Clicking this button will raise OnItemDeleting event. I have specified DeleteListViewItem method for this event and have written following code.
/// <summary>
/// Fires when delete link is clicked
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void DeleteListViewItem(object sender, ListViewDeleteEventArgs e)
{
int autoID = int.Parse(ListView1.DataKeys[e.ItemIndex].Value.ToString());

// insert records into database
using (SqlConnection conn = new SqlConnection(_connStr))
{
string Sql = "delete from Details where AutoID = @AutoID";
conn.Open();
using (SqlCommand dCmd = new SqlCommand(Sql, conn))
{
dCmd.Parameters.AddWithValue("@AutoID", autoID);
dCmd.ExecuteNonQuery();
}
conn.Close();
lblMessage.Text = "Records Deleted Successfully.";
}

// Rebind the details
BindPersonDetails("Name ASC");
}
In the above code, first I get the key of that records using ListView.DataKeys[e.ItemIndex].Value and opened the connection and execute delete query. Once I am done with deleting records, I again re-bind the record into ListView using BindPersonalDetails (Code - 1) method.
Tip 6 - Paging records in ListView
To paginate records in the ListView control, I have used DataPager control (new control in ASP.NET 3.5) and specified its PagedControlID as my ListView (Code - 1). In order to paginate the records in ListView, I need to handle the OnPagePropertiesChanging event of the ListView. In this even I have called PagePropertiesChangingmethod and my code for this method looks like following:
/// <summary>
/// Fires when page links are clicked in the Page control
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void PagePropertiesChanging(object sender, PagePropertiesChangingEventArgs e)
{
DataPager1.SetPageProperties(e.StartRowIndex, e.MaximumRows, false);
// Rebind the data
BindPersonDetails("Name ASC");
}
In this method, I have called SetPageProperies method of the DataPager control and passed startindex and page size of the ListView control and re-bind the ListView control.
Tip 7 - Sorting records in ListView
This is a little tricky. As there is no HeaderTemplate or Header (for a column) kind of thing in the ListView control as in the case of GridView or DataGrid control so we need to add LinkButton/Button with CommandName as Sort and CommandArgument as the field names to sort (see Code - 1 under LayoutTemplate). Specifying Sort as the command name intimate the ListView control that it has to fire OnSorting event. In this event I have specified SortListViewRecords method and written the code like following:
/// <summary>
/// Fires when column name is clicked
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void SortListViewRecords(object sender, ListViewSortEventArgs e)
{
string sortExpression = e.SortExpression + " " + e.SortDirection;
BindPersonDetails(sortExpression);
}
In this method, I have got the SortExpression and Direction and passed it into my BindPersonalDetails method (this method is binding my ListView control. Code - 1). As this method is handling the sorting mechanism based on whatever sort expression we pass so after every click on the column our data in the ListView control will be sorted.

No comments:

Post a Comment