Click here to Skip to main content
Email Password   helpLost your password?

Introduction

As we all know, the usage of the Eval and Bind methods can be expensive. Controls that use this method with Data-Binding Expressions are GridView, DetailsView, FormView, Repeater, and ListView. These are actually Data-Bound controls which can be bound to Data Source controls such as an ObjectDataSource or SqlDataSource.

There are ways to lower the cost of usage of the Eval method. Here is an example of how to do this. If you are using these controls (data-bound web controls) for enterprise web applications with several thousands of clicks per minute, the Eval method isn’t really the best solution. And of course, everything is hard-coded in HTML.

In this example, we are not going to use the Eval or Bind methods, nor are we are going to use Data Source controls. We are going to do everything from the server side. For this example to work properly, you need to download the .NET Framework 3.5 Service Pack 1 Beta.

Why ListView? This control has one very important event that we are going to heavily manipulate - ItemDataBound. Also, it has templates, e.g., ItemTemplate and EditItemTemplate. Our example is going to bind the data from a DataSet, edit this data, and update it.

Using the code

We are going to have Label controls in the ItemTemplate and TextBox controls in the EditItemTemplate. In the “edit mode”, every Label is going to be switched with a TextBox.

protected void Page_Load(object sender, EventArgs e)
{
    if (ProductsListView.EditItem == null)
    {
        ProductsListView.DataSource = LoadDataSet();
        ProductsListView.DataBind();
    }
}

As you can see, we are checking if this is “view mode” or “edit mode” to bind the right data to the ListView control. This will be more clear as we get to the other event handlers. After we call the DataBind method, the ItemDataBound event is fired.

protected void ProductsListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{

    ListViewDataItem dataItem = (ListViewDataItem)e.Item;
    DataRowView drv = (DataRowView)dataItem.DataItem;
       
    if (ProductsListView.EditItem == null)
    {

        Label companyName = (Label)e.Item.FindControl("CompanyName");
        companyName.Text = drv["CompanyName"].ToString();

        Label city = (Label)e.Item.FindControl("City");
        city.Text = drv["City"].ToString();

        Label customerID = (Label)e.Item.FindControl("CustomerID");
        customerID.Text = drv["CustomerID"].ToString();

    }
    ...

Here, we are again checking which template is being rendered, because if we are in “view mode”, and we are looking for TextBox controls, we will get an error.

Now, all data from the DataSet is bound to Label controls in the ItemTemplate and the page is rendered.

item.JPG

The Edit button’s CommandName attribute is set to “Edit”. This is going to fire a new event - ItemEditing.

protected void ProductsListView_ItemEditing(object sender, ListViewEditEventArgs e)
{
    ProductsListView.EditIndex = e.NewEditIndex;
    ProductsListView.DataBind();
}

Now, we are setting the EditIndex property to the index of the item that is being edited. Again, calling the DataBind method which fires the ItemDataBound event:

    ...
    else if (ProductsListView.EditItem != null)
    {

        if (dataItem.DisplayIndex == ProductsListView.EditIndex)
        {

            TextBox nameTextBox = (TextBox)e.Item.FindControl("CompanyTextBox");
            nameTextBox.Text = drv["CompanyName"].ToString();

            TextBox cityTextBox = (TextBox)e.Item.FindControl("CityTextBox");
            cityTextBox.Text = drv["City"].ToString();

            TextBox customerID = (TextBox)e.Item.FindControl("CustomerIDTextBox");
            customerID.Text = drv["CustomerID"].ToString();

        }
    }

}

This code is the second part of “if statements” in the ItemDataBound event handler. Here, we are not looking for Label controls in ItemTemplate, but TextBox controls in EditItemTemplate (EditItem != null). Also, we want to bind the right row of data (DisplayedIndex == EditIndex).

edititem.JPG

Now, EditItemTemplate is rendered with data bound to the TextBox controls. From here, we can change the data in TextBox controls and try to update the changes. The Update button has the CommandName attribute set to “Update”. This is going to fire a new event, ItemUpdating.

protected void ProductsListView_ItemUpdating(object sender, ListViewUpdateEventArgs e)
{
  TextBox nameTextBox=(TextBox)ProductsListView.EditItem.FindControl("CompanyTextBox");
  TextBox cityTextBox=(TextBox)ProductsListView.EditItem.FindControl("CityTextBox");
  TextBox customerID=(TextBox)ProductsListView.EditItem.FindControl("CustomerIDTextBox");

  Update(nameTextBox.Text, cityTextBox.Text, customerID.Text);
        
  ProductsListView.EditIndex = -1;
  ProductsListView.DataSource = LoadDataSet();
  ProductsListView.DataBind();
}

Now that we are in the “edit mode”, we are looking for TextBox controls from the EditItem property.

Using values from TextBox controls, we update data to the database and close EditItemTemplate. Because all buttons cause a postback, we had on the beginning in the Page_Load, a check to bind data only if we are not in “edit mode”. Now that we are, we are binding a new updated DataSet in this event handler.

Clicking on the Cancel button with fire the ItemCanceling event.

protected void ProductsListView_ItemCanceling(object sender, ListViewCancelEventArgs e)
{
    ProductsListView.EditIndex = -1;
    ProductsListView.DataSource = LoadDataSet();
    ProductsListView.DataBind();
}

Same story applies for ItemUpdating; although data is not updated, we need to bind data from this event handler because we are in “edit mode”.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralThank You!
Karl Nicoll
1:07 1 Feb '10  
Just found this post after having an issue with editing items with a listview, and this post solved my problem! Thanks for sharing! Big Grin

- Karl
GeneralDataPager problem fixed!
Goloskokovic
3:47 2 Oct '09  
Just add to your page codebehind:

override protected void OnPreRender(EventArgs e)
{
ProductsListView.DataBind();
base.OnPreRender(e);
}
GeneralExcellent Post man
binomial.theorem
21:53 30 Sep '09  
was googling for almost 2hrs to find how to handle events fired from within a listview edititemtemplate controls. u rock!Thumbs Up
GeneralCan not access info
Stevishere
9:34 29 Oct '08  
You mention in the top of this article that "Here..." as a hyperlink to get some info.

When I click it,

I get this:

Server Error in '/' Application.
--------------------------------------------------------------------------------

Login failed for user 'manovich-7'.

Any ideas?

Stevishere
www.Em8s.net

AnswerRe: Can not access info
Goloskokovic
12:32 29 Oct '08  
Try
http://anishg.wordpress.com/2008/06/20/use-explicit-casting-instead-of-databindereval/
GeneralGreat post
lmerino
2:31 16 Oct '08  
I've saved the day Smile

Thank you!
GeneralGreat post but
Crown_Lager
13:22 22 Apr '08  
is it some way to handle the first item in the list?

It seems to be a bug in the listview.
When you set EditIndex = 0,
EditItem still is null.

Regards Peter Hansson
GeneralRe: Great post but
Scindy
10:54 5 May '08  
You need to ser EditIndex = -1
AnswerRe: Great post but [modified]
Goloskokovic
8:25 14 May '08  
Root of this problem may be in ListView control. If you debug .NET Framework source code of ListView.cs in line 368 stays:

if (_editIndex > 0 && _editIndex < Items.Count)
{
return Items[_editIndex];
}

it should be: _editIndex >= 0 && ...

modified on Tuesday, May 27, 2008 2:49 AM

AnswerRe: Great post but
Goloskokovic
22:27 3 Jun '08  
It appears that this issue has already been resolved in the latest SP1 beta, so you should be able to get the fix there.


Last Updated 9 Jun 2008 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010