2013-06-20 6 views
1

ASP.NET 4.0. Je souhaite autoriser les utilisateurs à afficher/modifier des éléments sur la licence d'un client. Une licence a des produits 1-M, et la liste des produits va augmenter avec le temps, donc je crée dynamiquement une liste de tous les produits (dans Page_Load) avec une case à cocher pour dire si une licence a ce produit, comme ceci:Les contrôles créés dynamiquement perdent des valeurs

CheckBox cbxProduct = new CheckBox(); 
cbxProduct.ID = "cbxProduct" + product.ID.ToString(); 

je peux trouver ces contrôles dynamiques et accéder à leurs valeurs lors de la publication à l'aide:

CheckBox cbxProd = (CheckBox)pnlLicenseDetails.FindControl("cbxProduct" + productID.ToString()); 

mais seulement si elles viennent d'être recréés dans Page_Load (ou Page_Init, ne semble pas à la matière). Le problème est que je veux que l'utilisateur puisse décocher une case pour retirer un produit de la licence, puis enregistrer les résultats. Mais pour trouver la case à cocher et déterminer sa valeur, je dois recréer les contrôles, ce qui, bien sûr, efface toute valeur entrée par l'utilisateur.

Si j'essaie de faire référence aux cases à cocher sans les recréer, j'obtiens bien sûr une erreur "référence d'objet non définie ...". J'ai donc besoin d'un moyen de capturer les valeurs entrées par l'utilisateur avant qu'elles ne soient effacées.

Suggestions?

Répondre

0

Vous devez créer des contrôles dynamiques dans Page_Init. Vous devez les créer de la même manière pour toutes les demandes. Cela signifie que vous devez exécuter le même code pour créer le contrôle et l'ajouter à la collection de contrôles à chaque fois que la page est chargée, indépendamment de IsPostBack ou non.

Aussi, je suggère que vous sauvegardiez l'instance du contrôle dynamique à une variable de membre privé ainsi vous ne devez pas appeler FindControl car cela est potentiellement cher.

Comme il semble que vous avez une liste de produits quelque part, voici un exemple en utilisant un dictionnaire pour stocker les cases à cocher:

public partial class _Default : Page 
{ 
    private Dictionary<Int32,CheckBox> _myDynamicCheckBoxes; 

    protected override void OnInit(EventArgs e) 
    { 
     _myDynamicCheckBoxes = new Dictionary<Int32,CheckBox>(); 

     foreach (var product in _listOfProducts) 
     { 
      var chkBox = new CheckBox {ID = "CheckBox" + product.ID.ToString()}; 
      _myDynamicCheckBoxes.Add(product.ID,chkBox); 
      //add the checkbox to a Controls collection 
     } 
    } 
} 

Ensuite, quelque part ailleurs dans votre code, lorsque vous avez un produit et que vous voulez pour trouver la case à cocher associée, vous pouvez utiliser: var aCheckBox = _myDynamicCheckBoxes[product.ID];

+0

Merci, @ matt-dot-net. Pouvez-vous expliquer l'alternative à FindControl? Je ne suis pas sûr de ce que vous voulez dire par variable privée. – SteveEx

+0

BTW, je l'ai mis en place de sorte que la fonction BuildControls est appelée dans Page_Init, indépendamment de PostBack. L'erreur "référence d'objet" persiste lorsque vous tentez d'enregistrer les modifications de l'utilisateur. Si j'appelle BuildControls à partir de l'événement SaveChanges, je reçois cette erreur, mais je reçois une erreur indiquant que plusieurs contrôles ont le même ID, car BuildControls est également dans Page_Init. – SteveEx

+2

Cette idée de dictionnaire était la balle d'argent que je cherchais. Merci, @ matt-dot-net! – SteveEx

Questions connexes