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 :

Gridview et colonne dynamique


Sujet :

ASP.NET

  1. #1
    Membre habitué
    Inscrit en
    Septembre 2007
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 169
    Points : 149
    Points
    149
    Par défaut Gridview et colonne dynamique
    Bonjour,
    voila depuis ce matin que je penche sur ce problème, et que je commence à m'arracher les cheveux...
    Le principe est assez simple, j'ai un gridview classique, avec plusieurs colonnes dedans, que je peux éditer et tout, ca marche bien.
    Le problème est que je rajoute des colonnes dynamiquements, que je veux aussi pouvoir modifier.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    foreach (DataRow r in d.Rows)
                {
                    string s = (string)r.ItemArray[0];
                    BoundField maColonne;
                    maColonne = new BoundField();
                    maColonne.HeaderText = s;
                    maColonne.DataField = s;
     
                    GridView1.Columns.Add(maColonne);
                    //mise à jour du select et de l'update
    }
    C'est à partir de là ou cela se complique.

    1er problème : ou ajouter les colonnes ?
    Si je les mets dans le PageLoad, elles sont ajoutés a chaque fois, et même entre les changements de page, et donc je peux me retrouver avec 1, 2, 3.. fois les colonnes ajoutées dans mon
    gridview.
    Si je désactive le viewstate et que je les ajoute à chaque fois, elles n'apparaissent plus en double, mais il me dit qu'il ne trouve pas les colonnes ajoutées dynamiquement lorsque je clique sur "Edit".

    Ensuite, je met à jour le select du gridview, pour faire des jointures sur les champs sélectionnés. Le résultat est correct.

    Maintenant, ca se corse quand je veux pouvoir modifier ces nouvelles colonnes.
    2ème problème : Je suis obligé de modifier le updatecommand de mon gridview et de rajouter des faux paramètres, sinon il me dit qu'il y a un problème dans les paramètres(les boundfield des colonnes ajoutées ne sont pas liés dans l'updatecommand).

    Pour mettre à jour ces champs, je déclenche une procédure : GridView1_OnRowUpdated dans laquelle je met à jour ces champs indépendamment.

    Dernier problème : j'ai voulu créer des template à la place des Boundfield pour mes colonnes supplémentaires, ils fonctionnent apparement correctement, sauf qu'on moment de récupérer les valeurs contenues dans ces champs pour mettre à jour la base de données, je n'arrive pas à accéder aux textbox... Je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    // s = "ID du textbox du templatefield en mode édition"
    string valeur = ((TextBox)GridView1.Rows[GridView1.EditIndex].FindControl(s)).Text;
    Voila, si vous voyez une solution pour au moins un de ces problèmes, n'hésitez pas, je vous en serais très reconnaissant. Merci

  2. #2
    Membre régulier

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    68
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 68
    Points : 104
    Points
    104
    Par défaut Quelques idées
    Pour le premier problème

    Placer l'ajout de colonne dans le Load me paraît un bon endroit. Je pense simplement qu'il faut placer cet ajout dans un test du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if(!Page.IsPostBack)
    {
       //---> Ajouter les colonnes
    }
    Pour le deuxième problème

    Pour avoir déjà eu à faire face à des situations similaires, l'utilisation d'un SqlDataSource risque de se révéler une vrai galère. Je suggère la création d'un DataSource / DataView propriétaire. Il faut prendre le temps de bien lire la documentation mais au final c'est plutôt simple.

    L'avantage de cette solution, c'est que quelque soit le nombre de colonnes du GridView, il transmettra leurs valeurs aux méthodes du DataView (ExecuteSelect, ExecuteUpdate, ExecuteDelete, ExecuteInsert). Et comme dans ces méthodes vous faites absolument tout ce que vous voulez... Libre à vous de construire et d'exécuter les requêtes SQL appropriées.

    Pour le troisième problème

    Je pense qu'il faut en premier lieu régler les deux premiers problèmes puis s'attaquer au troisième si il existe encore.

    Autre idée

    Je ne sais pas si c'est envisageable dans votre cas, mais si vous pouvez circonscrire à l'avance la liste des colonnes supplémentaires dont vous avez besoin, pourquoi ne pas toutes les créer puis les rendre visibles ou invisibles suivant les besoins. Reste à voir si c'est compatible avec votre situation et si l'éventuelle présence invisible de certaines colonnes ne rsique pas de parasiter vos traitements. A étudier...

    Bon travail.

  3. #3
    Membre habitué
    Inscrit en
    Septembre 2007
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 169
    Points : 149
    Points
    149
    Par défaut
    Merci beaucoup pour vos réponses mlbreton.

    Pour le 1er problème, effectivement en faisant comme cela, cela fonctionne parfaitement. Par contre il faut que je sorte la modification de l'objet sqldatasource pour le faire à chaque rafraichissement, car elle, elle n'est pas sauvegardée dans le viewstate.

    Pour le 2ème problème :
    J'ai fait quelques recherches, et si j'ai bien compris ce dont vous parlez, vous voudriez que je crée une nouvelle classe qui hériterais de DataSourceView, dans laquelle je définirais mes propres mises à jour, selection...
    D'après ce que j'ai pu voir cela serait plus "propre", mais je trouve cela un peu lourd vu que je ne vais l'utiliser que dans ce cas. S'il n'y a pas de solutions plus simples pour éviter de devoir "feinter" le updatecommand, je pense j'opterais pour cette solution.

    Le 3ème problème est toujours présent bien entendu.

    Et non, je ne peux pas "prévoir" les colonnes. Comme le laisse sous entendre ma 1ere requete, je récupère ces colonnes dans une autre table.

  4. #4
    Membre habitué
    Inscrit en
    Septembre 2007
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 169
    Points : 149
    Points
    149
    Par défaut
    Je ne pense pas que cela vienne de là, mais je vous donne mon code de mon champs templaté :
    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
    public void InstantiateIn(System.Web.UI.Control Container)
        {
            switch (ItemType)
            {
                case ListItemType.Header:
                    LinkButton header_ltrl = new System.Web.UI.WebControls.LinkButton();
                    header_ltrl.CommandName = "Sort";
                    header_ltrl.CommandArgument = FieldName;
                    header_ltrl.Text = "<b>" + FieldName + "</b>";
                    Container.Controls.Add(header_ltrl);
                    break;
                case ListItemType.Item:
                    Literal field_txt = new Literal();
                    field_txt.Text = String.Empty; //we will bind it later through 'OnDataBinding' event
                    field_txt.DataBinding += new EventHandler(OnDataBinding);
                    Container.Controls.Add(field_txt);
                    break;
                case ListItemType.EditItem:
                    TextBox field_txtbox = new TextBox();
                    field_txtbox.ID = FieldName;
                    field_txtbox.Text = String.Empty;
                    field_txtbox.DataBinding += new EventHandler(OnDataBinding);
                    Container.Controls.Add(field_txtbox);
                    break;
            }
        }
    Les valeurs s'affichent bien dans les champs, donc la procédure de binding fonctionne bien.

    Je ne comprends pas pourquoi cela ne marcherait pas après dans le onupdatedrow :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // s = "ID du textbox du templatefield en mode édition"
    string valeur = ((TextBox)GridView1.Rows[GridView1.EditIndex].FindControl(s)).Text;

  5. #5
    Membre habitué
    Inscrit en
    Septembre 2007
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 169
    Points : 149
    Points
    149
    Par défaut
    Le problème est enfin résolu, c'est parce qu'il manquait un databind après avoir ajouté toutes les colonnes templatés. Par contre il faut ajouter les colonnes templatés a chaque fois, et non plus seulement lorsque ce n'est pas un postback. Je sais pas trop pourquoi, mais sinon elles disparaissent

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

Discussions similaires

  1. gridview en édit mode avec colonnes dynamiques
    Par badi3a82 dans le forum ASP.NET
    Réponses: 1
    Dernier message: 24/06/2010, 13h34
  2. Réponses: 9
    Dernier message: 23/03/2010, 18h52
  3. [Débutant] Problème colonnes dynamiques GridView
    Par NiamorH dans le forum Général Dotnet
    Réponses: 1
    Dernier message: 01/10/2008, 14h56
  4. Réponses: 4
    Dernier message: 17/09/2008, 19h05
  5. libelles et entêtes de colonnes dynamiques
    Par valfredr dans le forum XMLRAD
    Réponses: 7
    Dernier message: 09/03/2004, 22h40

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