DropDownList creato dinamicamente perde ListItems su Postback
-
05-07-2019 - |
Domanda
Ho una pagina che contiene alcuni controlli creati dinamicamente (TextBox e DropDownList). Quando si verifica un postback, le caselle di testo mantengono i loro valori, ma gli elenchi a discesa perdono i loro ListItems. Questo è abbastanza confuso, dal momento che DropDownList a livello di pagina mantiene anche i suoi ListItems. Qualcuno può vedere cosa c'è che non va nel codice qui sotto?
Qualsiasi aiuto per risolvere questo problema sarebbe molto apprezzato.
<%@ Page Language="VB"%>
<script runat="server">
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs)
If Not Page.IsPostBack Then
ddlFixed.Items.Add(New ListItem("12", "13"))
ddlFixed.Items.Add(New ListItem("14", "15"))
End If
Dim i As Integer
For i = 0 To 3
Dim ddl As New DropDownList
ddl.ID = "ddlPage" & i
ddl.EnableViewState = True
If Not Page.IsPostBack Then
ddl.Items.Add(New ListItem("12", "13"))
ddl.Items.Add(New ListItem("14", "15"))
End If
pnlDynamic.Controls.Add(ddl)
Dim txtBx As New TextBox
txtBx.ID = "txtPage" & i
If Not Page.IsPostBack Then
txtBx.Text = "Preset"
End If
pnlDynamic.Controls.Add(txtBx)
Next
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server" enableviewstate="true">
<div>
<br />
<br />
<a href="Default.aspx">Get-Request</a>
<br />
<br />
<asp:Panel runat="server" ID="pnlDynamic" EnableViewState="true" />
<br />
<br />
<asp:DropDownList runat="server" ID="ddlFixed" />
<asp:Button runat="server" ID="btn" Text="Postback"/>
</div>
</form>
</body>
</html>
Soluzione
Ho trovato la soluzione che mi permetterà di mantenere il viewstate tra postback. Deve chiamare TrackViewState di ItemCollection.
CType(ddl.Items, IStateManager).TrackViewState()
Grazie a tutti per il vostro aiuto.
Questa è la soluzione funzionante:
<%@ Page Language="VB"%>
<script runat="server">
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs)
If Not Page.IsPostBack Then
ddlFixed.Items.Add(New ListItem("12", "13"))
ddlFixed.Items.Add(New ListItem("14", "15"))
End If
Dim i As Integer
For i = 0 To 3
Dim ddl As New DropDownList
ddl.ID = "ddlPage" & i
CType(ddl.Items, IStateManager).TrackViewState()
If Not Page.IsPostBack Then
ddl.Items.Add(New ListItem("12", "13"))
ddl.Items.Add(New ListItem("14", "15"))
End If
pnlDynamic.Controls.Add(ddl)
Dim txtBx As New TextBox
txtBx.ID = "txtPage" & i
If Not Page.IsPostBack Then
txtBx.Text = "Preset"
End If
pnlDynamic.Controls.Add(txtBx)
Next
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server" >
<div>
<br />
<br />
<a href="Default.aspx">Get-Request</a>
<br />
<br />
<asp:Panel runat="server" ID="pnlDynamic" />
<br />
<br />
<asp:DropDownList runat="server" ID="ddlFixed" />
<asp:Button runat="server" ID="btn" Text="Postback"/>
</div>
</form>
</body>
</html>
Altri suggerimenti
Un DDL manterrà i suoi elementi e la selezione quando viewstate è abilitato. Una casella di testo manterrà i suoi contenuti indipendentemente dal viewstate poiché l'html risultante viene riscritto sul server su un postback.
Trovo cortese che tu abbia tutte queste dichiarazioni viewstate nel tuo codice e markup.
Sta accadendo una delle varie cose:
- ViewState sul controllo è disabilitato
- ViewState sopra la gerarchia dei contrl è disabilitato (pagina, modulo, pannello)
- Stai aggiungendo dinamicamente il controllo troppo tardi nel ciclo di pagine per caricare la selezione da viewstate. Il caricamento in INIT dovrebbe andare bene.
Potrebbe essere necessario attivare esplicitamente ViewState per tali elenchi a discesa ...
EDIT: questo è ciò che intendo per il mio ultimo commento ...
<script runat="server">
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs)
If Not Page.IsPostBack Then
ddlFixed.Items.Add(New ListItem("12", "13"))
ddlFixed.Items.Add(New ListItem("14", "15"))
Dim i As Integer
For i = 0 To 3
Dim ddl As New DropDownList
ddl.ID = "ddlPage" & i
ddl.EnableViewState = True
ddl.Items.Add(New ListItem("12", "13"))
ddl.Items.Add(New ListItem("14", "15"))
pnlDynamic.Controls.Add(ddl)
Dim txtBx As New TextBox
txtBx.ID = "txtPage" & i
txtBx.Text = "Preset"
pnlDynamic.Controls.Add(txtBx)
Next
End If
End Sub
</script>
Uso sempre Page_Load
e non ho mai problemi come questo. Forse qualcosa che potresti guardare.
In genere associo i dati ai controlli la prima volta che la pagina viene caricata, dopodiché consento a Viewstate di gestire i postback, ecc. Tieni presente che suggeriscono di associare i dati durante Page_Load
...
Scopri http://support.microsoft.com/kb/305141
Eventi della pagina loadTOCNode (2, 'maggiori informazioni'); Durante il ciclo di vita di una pagina ASP.NET, alcuni eventi standard che sono esposti dall'oggetto Pagina sono usati frequentemente. Il framework di pagine ASP.NET si connette automaticamente (o collega) le istanze delegate appropriate in esecuzione tempo per questi metodi. Questo ti evita di dover scrivere la colla necessaria . Codice " L'elenco seguente mostra le istanze delegate che sono collegate a tempo di esecuzione nell'ordine in cui vengono sparati:Il seguente elenco descrive gli eventi che sono non-deterministico:
- Page_Init : durante questo evento, puoi inizializzare i valori o connettere qualsiasi gestori di eventi che potresti avere.
- Page_Load : durante questo evento, puoi eseguire una serie di azioni per crea la tua pagina ASP.NET per la prima volta o rispondi agli eventi sul lato client quel risultato da un post. La pagina e lo stato della vista di controllo sono stati ripristinati prima di questo evento. Utilizzare la proprietà della pagina IsPostBack per verificare se è la prima volta che pagina in elaborazione. Se è la prima volta, eseguire l'associazione dei dati. Anche, leggere e aggiornare le proprietà di controllo.
- Page_DataBind : l'evento DataBind viene generato quando viene chiamato il metodo DataBind nella pagina livello. Se chiami DataBind su singoli controlli, genera solo l'evento DataBind dei controlli sottostanti.
- Page_PreRender : L'evento PreRender viene generato appena prima che lo stato di visualizzazione venga salvato e il i controlli sono resi. È possibile utilizzare questo evento per eseguire qualsiasi ultimo minuto operazioni sui controlli.
- Page_Unload : al termine del rendering di una pagina, viene attivato l'evento Page_Unload . Questo evento è un buon posto per eseguire la pulizia finale lavoro. Ciò include elementi come la pulizia di connessioni di database aperte, scartando oggetti o chiudendo quei file aperti.
- Errore_pagina : se si verifica un'eccezione non gestita durante l'elaborazione della pagina, viene generato l'evento Errore . L'evento Errore ti dà l'opportunità di gestire con grazia errori.
- Page_AbortTransaction : gli eventi Transaction sono utili se si desidera indicare se una transazione ha successo o fallisce. Questo evento viene comunemente utilizzato per gli scenari del carrello in che questo evento può indicare l'esito positivo o negativo di un ordine. Quest'evento viene generato quando una transazione è stata interrotta.
- Page_CommitTransaction : questo evento viene generato quando una transazione è stata impegnata con successo.
Le voci dell'elenco in un elenco a discesa non sono memorizzate nello stato di visualizzazione. Dovrai aggiungerli ad ogni postback.
Ciò che è memorizzato nello stato di visualizzazione è l'indice selezionato, ovvero. il "valore" del controllo.
Modifica: Beh, sembra che abbia imparato qualcosa oggi. Sono corretto :-)