PRB: ASP.NET genera eventi di modifica anche se non si modifica il valore del controllo

Sintomi

In determinate circostanze, ASP.NET genera l'evento di modifica per un controllo Web ASP.NET, anche se non si modifica il controllo.

Causa

Alcuni controlli, come in un controllo DropDownList evento SelectedIndexChanged o TextChanged in un controllo TextBox , si affidano la registrazione dell'evento Change di utilizzare lo stato di visualizzazione. Questo problema si verifica quando si creano questi controlli in modo dinamico dopo l'evento è collegato.

Quando ASP.NET esegue il rendering della pagina nel browser, i controlli che vengono creati dinamicamente non sono un evento di modifica associato. Poiché non è presente alcun evento, ASP.NET non salva lo stato di visualizzazione. Si tratta di ottimizzazione dello stato di visualizzazione.

Quando la pagina viene eseguita il postback, e gli eventi siano associati, ASP.NET prevede che lo stato di visualizzazione, ma trova che non esiste. Questa differenza viene generato l'evento di modifica anche se il controllo non è stato modificato.

Risoluzione

Assicurarsi di collegare l'evento di modifica per i controlli creati dinamicamente prima che ASP.NET esegue il rendering della pagina. Ciò garantisce che lo stato di visualizzazione per il controllo esista.

Stato

Questo è il comportamento previsto.

Ulteriori informazioni

Procedura per riprodurre il comportamento

Creare il Web Form

  1. Creare una nuova applicazione ASP.NET di Visual Basic denominata ChangeFired.
  2. Aprire WebForm1 in modalità progettazione. Trascinare un controllo DataList , un controllo Button e un controllo DataSet nel form.
  3. Nella finestra di dialogo Aggiungi DataSet , fare clic su dataset non tipizzatoe quindi fare clic su OK. Mantenere i nomi predefiniti per tutti i controlli.
  4. Modificare l'insieme di tabelle per DataSet1. Aggiungere una nuova tabella denominata Tabella1.
  5. Modificare l'insieme di colonne per Table1. Aggiungere una nuova colonna denominata Column1.
  6. Fare clic su DataList1e quindi modificare la proprietà DataSource in DataSet1.
  7. DataList1destro, scegliere Modifica modelloe quindi fare clic su Modelli di elemento. Trascinare un controllo DropDownList nella sezione ItemTemplate .
  8. Fare clic su DropDownList1e aggiungere cinque elementi all'insieme di elementi. Impostare il testo e le proprietà del valore di questi elementi su uno,
    due, tre,
    4e 5rispettivamente.
  9. Impostare la proprietà AutoPostBack su true per DropDownList1.
  10. Modificare l'insieme DataBindings per DropDownList1. Aggiungere la seguente espressione di associazione personalizzata per la proprietà SelectedIndex :
    DataBinder.Eval(Container, "DataItem.Column1")
  11. Passare alla visualizzazione HTML. Impostare l'attributo trace su true nella direttiva @ Page , come segue:
    <%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx.vb" Inherits="ChangeFired.WebForm1" trace="true" %>

Aggiungere il File Code-Behind

  1. Destro WebForm1. aspx e quindi scegliere Visualizza codice.
  2. Aggiungere il seguente codice all'evento Page_Load :
    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. Creare una nuova routine Sub sotto all'evento Page_Load per gestire l'evento SelectedIndexChanged nel modo seguente:
    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

Eseguire l'esempio

  1. Eseguire la pagina. Si noti che i controlli DropDownList creati in modo dinamico contengano lo stato di visualizzazione di informazioni di traccia per la struttura di controllo.

    Ciò si verifica perché la chiamata al metodo DataBind crea dinamicamente i controlli DropDownList e associare il gestore eventi, dopo il metodo DataBind chiamato nell'evento Page_Load . Poiché i controlli dispongono di un gestore eventi, ottimizzazione dello stato di visualizzazione non ha luogo.
  2. Fare clic sul pulsante nella pagina. Si noti che si verifica un postback e viene eseguito solo il codice nell'evento Page_Load . Lo stato di visualizzazione esiste per i controlli DropDownList perché un gestore eventi sia associato al controllo.
  3. Modificare il valore in uno dei controlli DropDownList . Si noti che si verifica un postback. Si noti, inoltre, in ASP.NET viene generato l'evento Page_Load ed esegue l'evento DropDownList1_SelectedIndexChanged .
  4. Nell'evento DropDownList1_SelectedIndexChanged , chiamare il metodo DataBind per crearne di nuovi controlli DropDownList .

    Poiché l'evento SelectedIndexChanged non è associato a questi nuovi controlli DropDownList , ASP.NET utilizza l'ottimizzazione dello stato di visualizzazione e non salva lo stato di visualizzazione per i nuovi controlli DropDownList .
  5. Rivedere le informazioni di traccia per la struttura di controllo. Si noti che i controlli DropDownList non hanno lo stato di visualizzazione.
  6. Fare clic sul pulsante nella pagina. Si noti che si verifica il post back e si noti che ASP.NET viene eseguito l'evento Page_Load . Poiché associare l'evento SelectedIndexChanged ai controlli DropDownList , ASP.NET prevede che lo stato di visualizzazione da associare ai controlli.

    Tuttavia, poiché lo stato di visualizzazione non esiste, ASP.NET genera l'evento SelectedIndexChanged , anche se non si seleziona un elemento.

Risoluzione

Per risolvere questo problema, rimuovere il commento il codice nell'evento DropDownList1_SelectedIndexChanged in modo da associare i gestori eventi con i controlli appena creati.
Proprietà

ID articolo: 314809 - Ultima revisione: 30 gen 2017 - Revisione: 1

Feedback