2010-09-16 6 views
4

Je n'arrive pas à obtenir les valeurs d'entrée des contrôles créés dynamiquement dans ListView.Récupère les valeurs des contrôles ajoutés dynamiquement dans ListView

Voici mon ListView:

<asp:ListView ID="lvQuestions" runat="server" DataKeyNames="ProductQuestionId" onitemdatabound="lvQuestions_ItemDataBound"> 
    <LayoutTemplate> 
     <table> 
      <tr runat="server" id="itemPlaceholder"></tr> 
     </table> 
    </LayoutTemplate> 
    <ItemTemplate> 
      <tr> 
       <td><%# Eval("Question") %></td> 
       <td> 
        <asp:PlaceHolder ID="plControl" runat="server" /> 
        <asp:HiddenField ID="hfQuestionId" runat="server" /> 
       </td> 
      </tr> 
    </ItemTemplate>   
</asp:ListView> 
<asp:Button ID="btnSubmit" runat="server" Text="Submit" onclick="btnSubmit_Click" /> 

Dans mon ItemDataBound Handler j'ajoute une zone de texte ou un autre contrôle à la Placeholder. Le type de contrôle dépend de l'élément, mais pour le garder simple, supposons qu'il s'agit toujours d'une zone de texte. L'identifiant du contrôle est également dynamique.

// create a textbox control 
TextBox txtbx = new TextBox(); 
txtbx.ID = "txtQuestion_" + productQuestionId.ToString(); //productQuestionId is the datakey value of this ListViewItem 
placeholder.Controls.Add(txtbx); 

Lorsqu'un utilisateur clique sur le bouton, je dois pouvoir obtenir les valeurs qu'ils ont remplies.

Dans ma recherche, j'ai trouvé que je dois d'abord recréer les contrôles ajoutés dynamiquement afin d'obtenir les valeurs de ceux-ci en raison du cycle de vie de la page.

Voici ce que j'ai dans mon gestionnaire de bouton pour recréer les contrôles:

foreach (ListViewDataItem item in lvQuestions.Items) 
    { 
     HiddenField hdField = (HiddenField)item.FindControl("hfQuestionId"); 
     PlaceHolder plcHolder = (PlaceHolder)item.FindControl("plControl"); 
     TextBox txtbx = new TextBox(); 
     txtbx.ID = "txtQuestion_" + hdField.Value; 
     plcHolder.Controls.Add(txtbx); 
    } 

alors le bloc de code suivant dans le même gestionnaire je Réitérons par les ListViewDataItems et trouve le contrôle:

foreach (ListViewDataItem item in lvQuestions.Items) 
    { 
     HiddenField hdField = (HiddenField)item.FindControl("hfQuestionId"); 
     PlaceHolder plcHolder = (PlaceHolder)item.FindControl("plControl"); 
     TextBox txtbx = (TextBox)plcHolder.FindControl("txtQuestion_" + hdField.Value); 
     if (txtbx != null) 
     { 
      Response.Write("TextBox Found:" + txtbx.Text); 
     } 
    } 

La zone de texte est trouvée, mais il n'y a pas de valeur. C'est comme si je venais d'écrire sur les zones de texte avec de nouvelles dans le bloc précédent. Si je supprime le bloc de code précédent, aucune zone de texte n'est trouvée.

Quelqu'un peut-il m'aider s'il vous plaît avec ce qui me manque ici?

Merci.

Répondre

3

Comme vous l'avez déjà découvert, il s'agit d'un problème lié au cycle de vie. Essayez de créer votre contrôle dynamique dans l'événement ListView.ItemCreated au lieu de l'événement ListView.ItemDataBound.

+0

Merci Phaedrus, cela a fonctionné! Je ne lis jamais rien sur la création de mes contrôles dans l'événement ItemCreated. J'ai déplacé la création ici et supprimé mon bloc de code pour recréer les contrôles dans le gestionnaire de soumission de bouton. Merci encore. – DahlinDev

1

Je pense que le problème ici est que le cycle de vie n'a aucune chance de remplir les contrôles avec leurs valeurs soumises avant que vous essayez de lire ces valeurs.

Généralement, si j'allais faire quelque chose comme ceci, je recréerais les contrôles dans l'événement Page_Init, qui se produit avant que les valeurs soient chargées dans les contrôles. Vous pouvez également le faire dans l'événement Init d'un contrôle particulier, mais c'est là que les contrôles supplémentaires doivent être ajoutés de nouveau à la page.

+0

J'ai essayé d'ajouter la recréation des contrôles dans le Page_Init. J'ai ajouté la logique, si (Page.IsPostBack && lvQuestions.Visible) ainsi seulement les recréer quand le formulaire a été soumis et les questions sont réellement affichées. Les contrôles n'ont pas été trouvés en faisant cela. – DahlinDev

0

Cela ne fonctionne pas pour moi, donc je devais le faire dans l'appel PreInit

protected override void OnPreInit(EventArgs e) 
    { 
     base.OnPreInit(e); 

     foreach (ListViewDataItem item in lvQuestions.Items) 
     { 
      HiddenField hdField = (HiddenField)item.FindControl("hfQuestionId"); 
      PlaceHolder plcHolder = (PlaceHolder)item.FindControl("plControl"); 
      if (hdField != null && plcHolder != null) 
      { 
       TextBox txtbx = new TextBox(); 
       txtbx.ID = "txtQuestion_" + hdField.Value; 
       plcHolder.Controls.Add(txtbx); 
      } 
     } 

    } 

Et je me suis déplacé cette méthode de retour à l'événement ItemDataBound

protected void lvQuestions_ItemDataBound(object sender, ListViewItemEventArgs e) 
    { 
     object datakey = lvQuestions.DataKeys[e.Item.DataItemIndex].Value; //get datakey here 

     TextBox txtbx = new TextBox(); 
     txtbx.EnableViewState = true; 
     txtbx.ID = "txtQuestion_" + datakey.ToString(); //productQuestionId is the datakey value of this ListViewItem 
     PlaceHolder pl = e.Item.FindControl("plControl") as PlaceHolder; 
     HiddenField hf = e.Item.FindControl("hfQuestionId") as HiddenField; 
     if (pl != null) 
      pl.Controls.Add(txtbx); 
     if (hf != null) 
      hf.Value = datakey.ToString(); 
    } 

Ensuite, il a commencé à travailler .

Questions connexes