IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

ASP.NET Discussion :

[Gérer des controles dynamiquement] Conseils d'implémentation


Sujet :

ASP.NET

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 29
    Points : 12
    Points
    12
    Par défaut [Gérer des controles dynamiquement] Conseils d'implémentation
    Bonjour,

    J'aimerais savoir si une meilleure implémentation de ce que je veux faire existe (probablement que oui ). Mise en situation :

    J'ai une liste de catégories que j'affiche dans une BulletedList à partir d'une base de données. Sur le clic d'un élément dans la liste je souhaite créer une série de contrôles à partir d'informations de la base de données telles que le type (TextBox, DropDownList, CheckBoxList, RadioButtonList), une position ordonnée, une valeur par défaut, etc... En ce moment, j'arrive à créer les contrôles que j'attache à un PlaceHolder dans ma page ASPX.

    Le problème survient quand j'appuie sur le bouton pour sauvegarder les informations du formulaire créé dynamiquement dans la base de données. En effet, tous mes contrôles créés dynamiquement disparaissent et je n'ai plus accès à l'information qu'ils contenaient...

    Quelle est la bonne façon de faire ce que j'ai décris?

    ** Si quelqu'un pouvait aussi m'éclairer sur le fait que les variables globales à ma classe sont réinitialisées à tous les PostBack, de ce fait, il m'est impossible de conserver une valeur... On doit utiliser le ViewState pour ce faire? **

    Voici mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
     
    using System;
    using System.Collections.Generic;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using ChecklistsPortal.Lib.BusinessObjects;
     
    namespace ChecklistsPortal
    {
        public partial class WebChanges : System.Web.UI.Page
        {
            private FeatureTypeCollection featColl = FeatureTypeCollection.GetAll();
     
            protected void Page_Load(object sender, EventArgs e)
            {
                loadFeatureTypesList();
            }
     
            private void loadFeatureTypesList()
            {
                blFeatureTypes.DataSource = featColl;
                blFeatureTypes.DataTextField = "FeatureTypeName";
                blFeatureTypes.DataValueField = "FeatureTypeId";
                blFeatureTypes.DataBind();
            }
     
            private void loadTemplateFieldsList(int featureTypeId)
            {
                TemplateFieldCollection temfColl = TemplateFieldCollection.GetByFeatureId(featureTypeId);
     
                foreach (TemplateFieldBO temf in temfColl)
                {
                    WebControl wcFieldType = null;
     
                    if (temf.FieldType.FieldTypeName == "TextBox")
                    {
                        wcFieldType = new TextBox();
                        wcFieldType.ID = "txtTemplateField_" + temf.TemplateFieldId;
                    }
                    else if (temf.FieldType.FieldTypeName == "DropDownList")
                    {
                        wcFieldType = new DropDownList();
                        wcFieldType.ID = "ddlTemplateField_" + temf.TemplateFieldId;
     
                        ((DropDownList)wcFieldType).Items.Add(new ListItem(temf.TemplateFieldValue, temf.TemplateFieldId.ToString()));
     
                        foreach (TemplateFieldBO temfChild in temf.TemplateFieldChildren)
                        {
                            ((DropDownList)wcFieldType).Items.Add(new ListItem(temfChild.TemplateFieldValue, temfChild.TemplateFieldId.ToString()));
                        }
                    }
                    else if (temf.FieldType.FieldTypeName == "CheckBoxList")
                    {
                        wcFieldType = new CheckBoxList();
                        wcFieldType.ID = "cblTemplateField_" + temf.TemplateFieldId;
     
                        foreach (TemplateFieldBO temfChild in temf.TemplateFieldChildren)
                        {
                            ((CheckBoxList)wcFieldType).Items.Add(new ListItem(temf.TemplateFieldValue, temf.TemplateFieldId.ToString()));
                        }
                    }
                    else if (temf.FieldType.FieldTypeName == "RadioButtonList")
                    {
                        wcFieldType = new RadioButtonList();
                        wcFieldType.ID = "rblTemplateField_" + temf.TemplateFieldId;
     
                        foreach (TemplateFieldBO temfChild in temf.TemplateFieldChildren)
                        {
                            ((RadioButtonList)wcFieldType).Items.Add(new ListItem(temf.TemplateFieldValue, temf.TemplateFieldId.ToString()));
                        }
     
     
     
                    }
     
                    if (wcFieldType != null)
                    {
                        Label lblFieldName = new Label();
                        lblFieldName.ID = "lblTemplateField_" + temf.TemplateFieldId;
                        lblFieldName.Text = temf.TemplateFieldName + " :";
                        lblFieldName.AssociatedControlID = wcFieldType.ID;
     
                        LiteralControl listItem = new LiteralControl("<li>");
                        LiteralControl divContainer = new LiteralControl("<div>");
                        LiteralControl divContainerClose = new LiteralControl("</div>");
                        LiteralControl listItemClose = new LiteralControl("</li>");
     
                        phTemplateFields.Controls.Add(listItem);
                        phTemplateFields.Controls.Add(divContainer);
                        phTemplateFields.Controls.Add(lblFieldName);
                        phTemplateFields.Controls.Add(wcFieldType);
                        phTemplateFields.Controls.Add(divContainerClose);
                        phTemplateFields.Controls.Add(listItemClose);
                    }
                }
            }
     
            private void saveModificationsWeb()
            {
                // Sauvegarder les informations
                // Les controles n'existent plus rendu ici, alors c'est impossible!!
            }
     
            protected void blFeatureTypes_Click(object sender, BulletedListEventArgs e)
            {
                loadTemplateFieldsList(featColl[e.Index].FeatureTypeId);
            }
     
            protected void btnSaveTemplateFields_Click(object sender, EventArgs e)
            {
                saveModificationsWeb();
            }
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    <%@ Page Title="" Language="C#" MasterPageFile="~/ChecklistsPortal.Master" AutoEventWireup="true" CodeBehind="WebChanges.aspx.cs" Inherits="ChecklistsPortal.WebChanges" %>
     
    <asp:Content ID="ContentHead" ContentPlaceHolderID="head" runat="server">
    </asp:Content>
    <asp:Content ID="ContentBody" ContentPlaceHolderID="contentMasterPage" runat="server">
        <div>
            <asp:Label ID="lblSelectFeatureType" runat="server" Text="Select a feature type : "></asp:Label>
            <asp:BulletedList runat="server" 
                ID="blFeatureTypes" 
                DisplayMode="LinkButton" 
                onclick="blFeatureTypes_Click">
            </asp:BulletedList>
        </div>
        <div>
            <asp:UpdatePanel ID="upTemplateFields" runat="server">
                <ContentTemplate>
                    <asp:Label ID="Label1" runat="server" Text="0"></asp:Label>
                    <ul>
                        <asp:PlaceHolder ID="phTemplateFields" runat="server"></asp:PlaceHolder>
                    </ul>
                    <asp:Button ID="btnSaveTemplateFields" runat="server" Text="Save" 
                        onclick="btnSaveTemplateFields_Click" />
                </ContentTemplate>
                <Triggers>
                    <asp:AsyncPostBackTrigger ControlID="blFeatureTypes" EventName="Click" />
                </Triggers>
            </asp:UpdatePanel>
        </div>
    </asp:Content>
    Images attachées Images attachées   

  2. #2
    Membre expérimenté Avatar de Arthis
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 265
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : Italie

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 265
    Points : 1 352
    Points
    1 352
    Par défaut
    Il faut que tes controles soient crées dans le oninit de ta page. C'est un probleme de cycle de vie de ta page.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 29
    Points : 12
    Points
    12
    Par défaut
    Comment puis-je passer en paramètre quel élément du BulletedList a été cliqué?

    J'ai essayé avec le ViewState de faire quelque chose comme ca :

    Les évènements étant exécutés APRES le Page_Load, si je modifie le ViewState dans mon évènement, alors dans le Page_Init je ne saurai pas quels contrôles je dois créer Sauf si je ne me trompe?

    EX :

    L'utilisateur clique sur le premier lien du BulletedList (index 0)

    Postback:
    - Page_Init => loadTemplateFields((int)ViewState["FeatureTypeId"]);
    - Page_Load => ...
    - BulletedList_Click => ViewState["FeatureTypeId"] = e.index;

    Du coup, le ViewState est toujours un coup en retard...

  4. #4
    Membre expérimenté Avatar de Arthis
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 265
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : Italie

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 265
    Points : 1 352
    Points
    1 352
    Par défaut
    tu dois créer tes controles à deux endroits :

    Dans l'evenement de ta page (Bullet list) afin de les creer une permiere fois
    Dans le oninit , afin de pouvoir recuperer els evenements sur ceux lors du postback.

    Ensuite, je ne sais pas si ton projet est de creer des formulaires dynamiques, mais si tu peux eviter, fais le. cela te rapportera plus de rigidité et de problemes qu'autre chose...

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 29
    Points : 12
    Points
    12
    Par défaut
    En fait je recherche des conseils pour que ma solution soit la mieux adaptée. Peut-être qu'en donnant plus de détails tu sauras m'éclairer?

    Je dois faire un formulaire pour qu'un utilisateur puisse entrer des données dans la base de données. Il existe peut-être 200-300 champs possible qu'il peut remplir (selon un format différent, un champs texte (un entier, une date, un texte, ou un autre format très précis comme Longitude/Latitude), une liste déroulante) et seulement ceux contenant de la nouvelle information sont sauvegardés. Les champs sont séparés par catégories pour faciliter la présentation à l'utilisateur pour qu'il ne soit pas trop perdu devant tous ces champs. L'utilisateur doit pouvoir ajouter/modifier/supprimer des champs supplémentaires comme bon lui semble.

    Vu le nombre de champs, je ne peux pas me permettre de faire une table avec 200-300 colonnes et de simplement la liée comme DataSource à un contrôle .NET De plus, chaque fois que des modifications sont sauvegardées, une nouvelle entrée (pour chaque champs modifiés) dans la base de donnée est ajoutée pour pouvoir garder l'historique des modifications.

    Ci-joint une petite partie du schéma de la base de données.

    Crois-tu qu'il est possible de faire autrement??
    Images attachées Images attachées  

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 29
    Points : 12
    Points
    12
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    ...
            protected void Page_Init(object sender, EventArgs e)
            {
                featColl = FeatureTypeCollection.GetAll();
     
                loadFeatureTypesList();
     
                if (ViewState["SelectedFeatureType"] == null)
                    ViewState["SelectedFeatureType"] = 0;
     
                if (IsPostBack)
                    loadTemplateFieldsList((int)ViewState["SelectedFeatureType"]);
            }
    ...
            protected void blFeatureTypes_Click(object sender, BulletedListEventArgs e)
            {
                ViewState["SelectedFeatureType"] = featColl[e.Index].FeatureTypeId;
                loadTemplateFieldsList((int)ViewState["SelectedFeatureType"]);
            }
    Si je comprends bien, je construis 2 fois mes controles à tous les PostBack?

  7. #7
    Membre confirmé
    Avatar de topolino
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    1 901
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 901
    Points : 637
    Points
    637
    Par défaut
    Pour recuperer les evenements de tes controles, sert toi de la propagation d'evenement.

    Il y a aussi le chargement dynamique de tes control a l'endroit ou tu le desire ds ta page avec le LoadControl. Tu pourras alors acceder à ses proprietes.

    Sinon il y a le page.items.
    MCTS Microsoft.
    La conception : Prendre le temps pour gagner du temps.

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 29
    Points : 12
    Points
    12
    Par défaut
    Merci pour ta réponse topolino, pourrais-tu être un peu plus précis sur l'utilisation de la propagation d'évènement / LoadControl / Page.Items

    Je commence à voir la lumière!

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 29
    Points : 12
    Points
    12
    Par défaut
    J'ai lu sur les 3 sujets mentionnés précédemment (Google) et je ne comprends pas comment cela pourrait aider à mon problème?

    Quelqu'un peut m'expliquer?

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 29
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par JeePI196 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    ...
            protected void Page_Init(object sender, EventArgs e)
            {
                featColl = FeatureTypeCollection.GetAll();
     
                loadFeatureTypesList();
     
                if (ViewState["SelectedFeatureType"] == null)
                    ViewState["SelectedFeatureType"] = 0;
     
                if (IsPostBack)
                    loadTemplateFieldsList((int)ViewState["SelectedFeatureType"]);
            }
    ...
            protected void blFeatureTypes_Click(object sender, BulletedListEventArgs e)
            {
                ViewState["SelectedFeatureType"] = featColl[e.Index].FeatureTypeId;
                loadTemplateFieldsList((int)ViewState["SelectedFeatureType"]);
            }
    Si je comprends bien, je construis 2 fois mes controles à tous les PostBack?
    À moins d'avoir mal compris, ce code ne me permet pas de manipuler les valeurs entrées dans les champs créés dynamiquement dans l'évènement Click du bouton. Ils disparaissent complètement malgré le Page_Init()...

  11. #11
    Membre expérimenté Avatar de Arthis
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 265
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : Italie

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 265
    Points : 1 352
    Points
    1 352
    Par défaut
    Effectivement cela fait beaucoup de champs a gerer. T'es tu renseigner sur les outils de generation automatique de code? Dans ton cas cela peut s'averer salvateur. Je ne sais aps trop ce qui il en est personnellement, mais pose la question autour de toi on sait jamais.

    sinon voici une petite maquette pour t'expliquer le principe que je te donnais plus haut :

    C'est bien evidemment juste une ebauche pour te donner un peu la direction à prendre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    <%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
     
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>Untitled Page</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:LinkButton ID="C_LBtn_Choix1" runat="server" OnClick=CreateFormulaire CommandArgument="1">
                Option 1 : Un champ texte seul.
             </asp:LinkButton><br />
            <asp:LinkButton ID="C_LBtn_Choix2" runat="server" OnClick=CreateFormulaire CommandArgument="2"> 
                Option 2 : Un champ texte seul avec un dropdwnlist..
            </asp:LinkButton>
            <br />
            <br />
            <asp:PlaceHolder runat=server ID=C_PH_Formulaire>
                <asp:LinkButton runat=server ID=C_Lbtn_Save OnClick=SaveForm >save</asp:LinkButton>
            </asp:PlaceHolder>
     
        </div>
        </form>
    </body>
    </html>

    et le code behind de la page :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    using System;
    using System.Configuration;
    using System.Data;
    using System.Linq;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Xml.Linq;
     
    public partial class _Default : System.Web.UI.Page 
    {
     
        public int? TemplateId
        {
            get { return (int?)Session["templateId"]; }
            set { Session["templateId"] = value; }
        }
     
        private void GenerateForm(int FormTemplateId)
        {
            TextBox tb =null;
            switch (FormTemplateId)
    	        {
                    case 1:
                        tb = new TextBox();
                        tb.ID = "C_TB_Form" + FormTemplateId;
                        C_PH_Formulaire.Controls.Add(tb);                  
                        break;
                    case 2:
                        tb = new TextBox();
                        tb.ID = "C_TB_Form" + FormTemplateId;
                        C_PH_Formulaire.Controls.Add(tb);
                        DropDownList ddl = new DropDownList();
                        ddl.ID = "C_TB_Form" + FormTemplateId;
                        C_PH_Formulaire.Controls.Add(tb);
                        break;
    	        }
            C_Lbtn_Save.CommandArgument = FormTemplateId.ToString();
        }
     
        protected override void OnInit(EventArgs e)
        {
            //permet de regenerer les elements afin de pouvoir interagir avec eux
            if (TemplateId.HasValue)
                GenerateForm(TemplateId.Value);
            base.OnInit(e);
        }
     
        protected void Page_Load(object sender, EventArgs e)
        {
     
        }
     
        protected void CreateFormulaire(object sender, EventArgs e)
        {
            LinkButton Lbtn = null;
     
            Lbtn = sender as LinkButton;
     
            if (Lbtn != null)
            {
                //cree les composant pour affichage lors du premier appel
                TemplateId = int.Parse(Lbtn.CommandArgument);
                GenerateForm(TemplateId.Value);
     
            }
        }
     
        protected void SaveForm(Object sender, EventArgs e)
        {
            TextBox tb = null;
     
            switch (C_Lbtn_Save.CommandArgument)
            {
                case "1":
                    tb= (TextBox)C_PH_Formulaire.FindControl("C_TB_Form"+ C_Lbtn_Save.CommandArgument);
                    if (tb != null)
                    Response.Write("Option 1<BR>");
                    Response.Write("Le Champ " + tb.ID+"<BR>");
                    Response.Write(tb.Text+"<BR>");
                    break;
                case "2":
                    tb = (TextBox)C_PH_Formulaire.FindControl("C_TB_Form" + C_Lbtn_Save.CommandArgument);
                    if (tb != null)
                        Response.Write("Option 2<BR>");
                    Response.Write("Le Champ " + tb.ID + "<BR>");
                    Response.Write(tb.Text + "<BR>");
                    break;
            }
        }
    }

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 29
    Points : 12
    Points
    12
    Par défaut
    WOAH!!!!!

    Ca fonctionne à merveille!!!! MERCIIIIIIIIIII!!!

    Tu es le King!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 02/08/2006, 23h54
  2. [PHP-JS] Gérer des listBox dynamiquement
    Par joquetino dans le forum Langage
    Réponses: 5
    Dernier message: 11/07/2006, 16h57
  3. [FLASH 8] gérer des boutons dynamiquement
    Par gregooo dans le forum Flash
    Réponses: 1
    Dernier message: 04/02/2006, 21h22
  4. Réponses: 6
    Dernier message: 18/04/2005, 21h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo