You are currently offline, waiting for your internet to reconnect

PRB: ASP.NET fires Change events even if you do not change the control value

This article was previously published under Q314809
Under specific circumstances, ASP.NET fires the Change event for an ASP.NET Web control even if you do not change the control.
Some controls, such as the SelectedIndexChanged event in a DropDownList control or the TextChanged event in a TextBox control, rely on the registration of the Change event to use view state. You encounter this problem when you create these controls dynamically after the event is hooked up.

When ASP.NET renders the page to the browser, the controls that are created dynamically do not have an associated Change event. Because no event is present, ASP.NET does not save the view state. This is called View State Optimization.

When the page is posted back, and when the events are hooked up, ASP.NET expects view state but finds that none exists. This difference fires the Change event even if the control has not been changed.
Make sure that you hook up the Change event for dynamically created controls before ASP.NET renders the page. This ensures that view state for the control exists.
This behavior is by design.

Steps to Reproduce the Behavior

Create the Web Form

  1. Create a new Visual Basic ASP.NET application named ChangeFired.
  2. Open WebForm1 in designer mode. Drag a DataList control, a Button control, and a DataSet control onto the form.
  3. In the Add DataSet dialog box, click Untyped dataset, and then click OK. Keep the default names for all of the controls.
  4. Edit the Tables collection for DataSet1. Add a new table named Table1.
  5. Edit the Columns collection for Table1. Add a new Column named Column1.
  6. Click DataList1, and then change the DataSource property to DataSet1.
  7. Right-click DataList1, point to Edit Template, and then click Item Templates. Drag a DropDownList control to the ItemTemplate section.
  8. Click DropDownList1, and then add five items to the Items collection. Set the Text and the Value properties of these items to one, two, three, four, and five respectively.
  9. Set the AutoPostBack property to true for DropDownList1.
  10. Edit the DataBindings collection for DropDownList1. Add the following custom binding expression to the SelectedIndex property:
    DataBinder.Eval(Container, "DataItem.Column1")					
  11. Switch to HTML view. Set the trace attribute to true in the @ Page directive as follows:
    <%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx.vb" Inherits="ChangeFired.WebForm1" trace="true" %>					

Add the Code-Behind File

  1. Right-click WebForm1.aspx, and then click View Code.
  2. Add the following code to the Page_Load event:
    DataSet1.Tables(0).Rows.Add(New Object() {"1"})DataSet1.Tables(0).Rows.Add(New Object() {"2"})DataSet1.Tables(0).Rows.Add(New Object() {"3"})DataSet1.Tables(0).Rows.Add(New Object() {"4"})If Not IsPostBack Then  DataBind()End IfDim objItem As DataListItemFor Each objItem In DataList1.Items  AddHandler CType(objItem.FindControl("DropDownList1"), _  DropDownList).SelectedIndexChanged, AddressOf DropDownList1_SelectedIndexChanged  If Not objItem.FindControl("DropDownList1") Is Nothing Then    Trace.Write("Added SelectedIndexChanged Handler")  End IfNext					
  3. Create a new Sub procedure below the Page_Load event to handle the SelectedIndexChanged event as follows:
    Private Sub DropDownList1_SelectedIndexChanged(ByVal sender As System.Object, _ByVal e As System.EventArgs)  DataBind()  Trace.Write("SelectedIndexChanged, DataBind()")  'Uncomment the following code to resolve this problem.  'Dim objItem As DataListItem  'For Each objItem In DataList1.Items  '  AddHandler CType(objItem.FindControl("DropDownList1"), _  '  DropDownList).SelectedIndexChanged, AddressOf DropDownList1_SelectedIndexChanged  'NextEnd Sub					

Run the Sample

  1. Run the page. Notice that the dynamically created DropDownList controls contain view state in the trace information for the Control tree.

    This occurs because the call to the DataBind method dynamically creates the DropDownList controls, and you hook up the event handler after the DataBind call in the Page_Load event. Because the controls have an event handler, View State Optimization does not take place.
  2. Click the button on the page. Notice that a post back occurs, and only the code inside the Page_Load event runs. View state exists for the DropDownList controls because an event handler is associated with the control.
  3. Change the value in one of the DropDownList controls. Notice that a post back occurs. In addition, notice that ASP.NET fires the Page_Load event and runs the DropDownList1_SelectedIndexChanged event.
  4. In the DropDownList1_SelectedIndexChanged event, call the DataBind method again to create new DropDownList controls.

    Because the SelectedIndexChanged event is not hooked up to these new DropDownList controls, ASP.NET uses View State Optimization and does not save the view state for the new DropDownList controls.
  5. Review the trace information for the Control tree. Notice that the DropDownList controls do not have view state.
  6. Click the button on the page. Notice that the post back occurs, and notice that ASP.NET runs the Page_Load event. Because you hook the SelectedIndexChanged event to the DropDownList controls, ASP.NET expects view state to be associated with the controls.

    However, because view state does not exist, ASP.NET fires the SelectedIndexChanged event, even though you do not select an item.


To resolve this problem, uncomment the code in the DropDownList1_SelectedIndexChanged event so that the event handlers hook up with the newly created controls.
view state

Article ID: 314809 - Last Review: 05/03/2004 23:53:02 - Revision: 2.7

Microsoft ASP.NET 1.1, Microsoft ASP.NET 1.0

  • kbdatabinding kbevent kbprb kbservercontrols kbstate kbwebforms KB314809