DropDownList créé dynamiquement perd ListItems à la publication
-
05-07-2019 - |
Question
J'ai une page qui contient des contrôles créés dynamiquement (TextBox et DropDownList). Lorsqu'une publication a lieu, les TextBox conservent leurs valeurs, mais les DropDownLists perdent leurs ListItems. Cela est assez déroutant, car DropDownList au niveau de la page conserve également ses ListItems. Quelqu'un peut-il voir ce qui ne va pas avec le code ci-dessous?
Toute aide pour résoudre ce problème serait grandement appréciée.
<%@ 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>
La solution
J'ai trouvé la solution qui me permettra de conserver l'état de vue d'un postback à l'autre. Il s’agit d’appeler TrackViewState de ItemCollection.
CType(ddl.Items, IStateManager).TrackViewState()
Merci à tous pour votre aide.
Voici la solution de travail:
<%@ 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>
Autres conseils
Une DDL conservera ses éléments et sa sélection lorsque viewstate est activé. Une zone de texte conserve son contenu, quel que soit l'état de visualisation, car le code HTML résultant est écrit sur le serveur lors de la publication.
Je trouve intéressant que vous ayez toutes ces déclarations viewstate dans votre code et vos balises.
Il se passe entre autres choses:
- ViewState sur le contrôle est désactivé
- ViewState au-dessus de la hiérarchie de contrôle est désactivé (page, formulaire, panneau)
- Vous ajoutez dynamiquement le contrôle trop tard dans le cycle de page pour que la sélection soit chargée à partir de viewstate. Le chargement dans INIT devrait être correct.
Peut-être devez-vous activer explicitement le ViewState pour ces DropDownLists ...
EDIT: C’est ce que je veux dire par mon dernier commentaire ...
<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>
J'utilise toujours Page_Load
et je n'ai jamais de problèmes de ce genre. Peut-être que vous pourriez regarder quelque chose.
Je lie généralement les données aux contrôles lors du premier chargement de la page, puis laisse Viewstate gérer les publications, etc. Notez qu'ils vous suggèrent de lier les données lors de Page_Load
...
Découvrez http://support.microsoft.com/kb/305141
Événements de page loadTOCNode (2, 'moreinformation'); Au cours du cycle de vie d’une page ASP.NET, quelques événements standard qui sont exposés à partir de l’objet Page sont fréquemment utilisés. Le framework de page ASP.NET se connecte automatiquement aux instances de délégué appropriées lors de l'exécution (ou les connecte) temps pour ces méthodes. Cela vous évite d’écrire la "colle" nécessaire code. " La liste suivante présente les instances de délégué qui sont connectées à le temps d'exécution dans l'ordre dans lequel ils sont renvoyés:La liste suivante répertorie les événements qui sont non déterministe:
- Page_Init : lors de cet événement, vous pouvez initialiser des valeurs ou connecter tout gestionnaires d’événements que vous pourriez avoir.
- Page_Load : lors de cet événement, vous pouvez effectuer une série d’actions sur créer votre page ASP.NET pour la première fois ou répondre à des événements côté client qui résultent d'un post. L'état de la page et de la vue de contrôle a été restauré avant cet événement. Utilisez la propriété de page IsPostBack pour vérifier si c’est la première fois que le la page est en cours de traitement. Si c'est la première fois, effectuez une liaison de données. Également, lire et mettre à jour les propriétés du contrôle.
- Page_DataBind : l'événement DataBind est déclenché lorsque la méthode DataBind est appelée sur la page niveau. Si vous appelez DataBind sur des contrôles individuels, il ne déclenche que l'événement DataBind des contrôles situés en dessous.
- Page_PreRender : L'événement PreRender est déclenché juste avant l'enregistrement de l'état d'affichage et la les contrôles sont rendus. Vous pouvez utiliser cet événement pour effectuer une dernière minute opérations sur vos contrôles.
- Page_Unload : après le rendu d'une page, l'événement Page_Unload est déclenché. Cet événement est un bon endroit pour effectuer le nettoyage final travail. Cela inclut des éléments tels que le nettoyage des connexions de base de données ouvertes, supprimer des objets ou fermer les fichiers ouverts.
- Page_Error : si une exception non gérée se produit lors du traitement de la page, l'événement Erreur est déclenché. L'événement Erreur vous offre la possibilité de gérer avec élégance erreurs.
- Page_AbortTransaction : les événements de transaction sont utiles si vous souhaitez indiquer si une transaction réussit ou échoue. Cet événement est couramment utilisé pour les scénarios de panier dans auquel cet événement peut indiquer le succès ou l'échec d'une commande. Cet evènement se déclenche lorsqu'une transaction a été annulée.
- Page_CommitTransaction : cet événement se déclenche lorsqu'une transaction a été validée. avec succès.
Les éléments de liste dans une DropDownList ne sont pas stockés dans l'état d'affichage. Vous devrez les ajouter à chaque publication.
Ce qui est stocké dans l'état d'affichage est l'index sélectionné - c'est-à-dire. la 'valeur' ??du contrôle.
Modifier: Eh bien, il semble que j'ai appris quelque chose aujourd'hui. Je reste corrigé: -)