Notice: This website is an unofficial Microsoft Knowledge Base (hereinafter KB) archive and is intended to provide a reliable access to deleted content from Microsoft KB. All KB articles are owned by Microsoft Corporation. Read full disclaimer for more details.

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


View products that this article applies to.

Symptoms

Under specific circumstances, ASP.NET fires the Change event for an ASP.NET Web control even if you do not change the control.

↑ Back to the top


Cause

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.

↑ Back to the top


Resolution

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.

↑ Back to the top


Status

This behavior is by design.

↑ Back to the top


More information

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 If
    
    Dim objItem As DataListItem
    For 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 If
    Next
    					
  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
      'Next
    End 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.

Resolution

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

↑ Back to the top


Keywords: KB314809, kbwebforms, kbstate, kbservercontrols, kbprb, kbevent, kbdatabinding

↑ Back to the top

Article Info
Article ID : 314809
Revision : 9
Created on : 5/3/2004
Published on : 5/3/2004
Exists online : False
Views : 505