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

Linq Discussion :

Ajout de colonne dynamiquement dans un Gridview depuis une LinqDataSource


Sujet :

Linq

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 9
    Points : 5
    Points
    5
    Par défaut Ajout de colonne dynamiquement dans un Gridview depuis une LinqDataSource
    Bonjour à toutes et à tous,

    La question est la suivante :
    - Comment peut-on, sans les nommer, rajouter une colonne dans un Gridview. Actuellement je marque en dur la valeur String correspondante à ma colonne dans la propriété DataField d'une instance de l'objet BoundField.

    Un exemple vous aidera mieux à comprendre mon problème.

    J'ai une LinqDataSource comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    LinqDataSource ldsEnvironment = new LinqDataSource();
    ldsEnvironment.ID = "LinqDataSource1";
    ldsEnvironment.ContextTypeName="Link.DataClasses1DataContext";
    ldsEnvironment.TableName = "Environment";
    Page.Controls.Add(ldsEnvironment);
    Celle-ci n'a aucune instruction particulière et ramène donc l'intégralité des colonnes de ma Table "Environment".

    Pour attacher l'une des colonnes à un Gridview, je procède comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     //Création de la Gridview
    Gridview gvw = new Gridview();
    gvw.DataSourceID = "LinqDataSource1";
     
    //Création de la colonne
    BoundField bfCodeColumn = new BoundField();
    bfCodeColumn.DataField = "Code";
     
    //Ajout de la colonne au Gridview
    gvw.Columns.Add(bfCodeColumn);
     
    //Ajout du Gridview dans la Page
    Page.Controls.Add(gvw);
    On peut voir ici que je suis obligé d'écrire en dur le mot "Code".

    J'aimerai ne pas avoir besoin de l'écrire et pouvoir boucler sur la source de donnée ou autre de façon à récupérer le nom des colonnes une part une. Cela me permettrait de contextualiser l'affichage des colonnes dans mon Gridview en fonction des cas, voir mieux, afficher une nouvelle colonne en ajoutant une colonne en base de donnée... sans retoucher au code !

    Pour réaliser cela il me manque : la liste des colonnes ramenées (où la trouve t-on ?), le nombre de colonne ramenée pour boucler et/ou une valeur booléenne pouvant indiquer quand tout à été parcouru.

    J'ai fouillé dans la LinqDataSource, mais impossible de trouver cette liste. J'imagine que si les données son liée seulement en écrivant "Code", c'est qu'il y a un mécanisme qui vérifie que cette colonne existe bien pour l'ajouter ?

    Je n'ai pas trouver de quoi résoudre mon problème avec mes multiples recherches mais probablement que je n'ai pas cherché avec les bon mot-clé (effectivement parler de dynamique est souvent synonyme d'instanciation dans le code Behind).

    Merci d'avance pour vos aides, idées, renvoi vers articles, ou solutions.

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    826
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2006
    Messages : 826
    Points : 1 120
    Points
    1 120
    Par défaut
    Salut,

    Il y a bien le AutoGenerateColumns (accessible depuis le code, pas le designer) qui peut répondre à tes besoins ; cependant, cette technique impose de leur faire pour toutes les colonnes. En plus, il n'y a pas beaucoup de tuning possible (entête, type de colonne, ...)

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 9
    Points : 5
    Points
    5
    Par défaut AutoGenerateColumns
    Merci de t'être penché sur mon problème.

    Effectivement, en mettant la propriété AutoGenerateColumns à true les colonnes sont bien générées automatiquement.

    Cependant, quand je lie mes colonnes, ce ne sont pas réellement des BoundField que je lie, mais des classes étendus du BoundField (TextField, CalendarField, SelectField) que j'attribue en fonction du type des données que contiendra la colonne. Il faut donc que j'ai la main sur les colonnes que je lie pour instancier les bons objets.

    Je vais creuser un peu la question, mais mon problème reste entier.

    D'autres idées ?

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    826
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2006
    Messages : 826
    Points : 1 120
    Points
    1 120
    Par défaut
    Sinon, il reste toujours la méthode classique qui consiste lors du binding à inspecter ta source de données et récupérer le type de chaque colonne pour faire les ajouts de colonnes dans un gros switch.

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Oui, c'est ce que je compte faire dans la théorie mais dans la pratique je n'arrive pas à mettre la main sur mes colonnes dans la source de donnée.

    Il faut se servir de l'évènement DataBinding sur le Gridview et il y a possibilité de récupérer les informations ?

    Merci

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    826
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2006
    Messages : 826
    Points : 1 120
    Points
    1 120
    Par défaut
    Sinon regarde un peu du coté de LinqDataSource.Selected, c'est l'event déclenché après la récupération des données et avant le binding.

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 9
    Points : 5
    Points
    5
    Par défaut Evènement Select


    Voila ce que relève l'évènement. J'imagine qu'il n'y a pas moyen de boucler sur le nombre de propriété que contient l'une des entrées du tableau Result ?

    Parce que visuellement dans l'outil j'arrive à compter 5 colonnes, et je peux même voir leur nom avec le nom de variable... mais je ne vois pas du tout comment l'interpréter en code.

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    826
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2006
    Messages : 826
    Points : 1 120
    Points
    1 120
    Par défaut
    Si c'est possible via la réflection : c'est un moyen d'obtenir la structure des objets de manière dans le runtime. Par contre, c'est pas terrible en terme de perf. Cela dit tu n'as qu'a le faire une fois, afin de déterminer les colonnes de la grille, et mapper le nom des propriétés.

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    N'ayant aucunes autres pistes j'ai exploité l'objet envoyé lors de l'évènement Selected du LinqDataSource et à l'aide de la réflexion, j'arrive à retourner sous forme de liste le mes colonnes, mais cette approche est très bancale. Je sens que je ne m'y prends pas de la bonne façon.

    Il faudrait que je prévois un autre cas de traitement si le Select ne renvoi pas l'intégralité de ma classe "Environment". Effectivement dans le cas ou le retour n'est plus un objet de type Link.Environment mais un objet Dynamique, je récupère une erreur sur ce traitement.

    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
    protected void ldsEnvironment_Selected(object sender, LinqDataSourceStatusEventArgs e)
            {
                LinqDataSourceStatusEventArgs ldssea = e as LinqDataSourceStatusEventArgs;
    			//L'élément LinqDataSourceStatusEventArgs possède une propriété Result qui contient une List de Link.Environment ou d'objet Dynamique
    			//selon le Select de la source de donnée. [Pas de select donne un objet Link.Environment] et [new (Code, Status) donne un objet Dynamique]
                List<Link.Environment> ldsseaList = (List<Link.Environment>)ldssea.Result;
     
    			//Le traitement qui suit ne fonctionne que sur un objet Link.Environment
    			//On récupère le premier élément de la List
                Type ldsseaObj = ldsseaList.First().GetType();
     
    			//Pour chacune des méthodes existantes, on fait le traitement suivant
                foreach (MethodInfo mi in ldsseaObj.GetMethods())
                {
    				//Ce traitement isole uniquement les propriétés représentant les colonnes.
    				//Exemple : pour le traitement de get_Code, l'entrée satisfait les conditions.
                    if (!mi.IsFinal && mi.IsSpecialName && mi.Name.StartsWith("get_"))
                    {
    					//On rend le nom de la colonne sous forme de string : "get_Code" est donc "Code", l'un des champs de ma table
                        lb.Text += mi.Name.Replace("get_", "") + "<br />";
                        columnInDataSource.Add(mi.Name.Replace("get_", ""));
                    }
                }
            }
    Le problème vient de la ligne suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    List<Link.Environment> ldsseaList = (List<Link.Environment>)ldssea.Result;
    Je ne sais pas comment caster un object dynamique.

    Je me pose également une question, comment fait t-on des jointures avec une LinqDataSource ?

    Dernier problème, l'évènement Selected de linqDataSource se déclenche après le Page_Load dans lequel je lie mes colonnes. Pour les lier après cette évènement, ou est t-il le plus judicieux de faire la liaison (j'ai tester plusieurs évènement de la Page et du Gridview sans succès...

    Note : Le code suivant ne sert pas a grand chose dans un Selected. J'aurais pu me servir de la nomenclature de mon objet Link.Environment pour faire la même chose en dehors du Selected. Ce qui m'intéresse est plutôt du coté dynamique.

    A l'aide

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par cybermaxs Voir le message
    Salut,

    Il y a bien le AutoGenerateColumns (accessible depuis le code, pas le designer) qui peut répondre à tes besoins ; cependant, cette technique impose de leur faire pour toutes les colonnes. En plus, il n'y a pas beaucoup de tuning possible (entête, type de colonne, ...)
    Il n'y a pas un évènement pour reprendre la main juste après l'insertion de chaque colonne auto générée ?

    J'ai tester le RowDataBound pour voir si avec le "sender" je pourrai pas ajouté ou lire les colonnes du gridview mais sans succès...

    J'ai vu qu'il existe pour le Grdiview Winform les évènements ColumAdded ou DataBindingComplete mais elle ne semble pas exister pour du Webform...

Discussions similaires

  1. Comment ajouter plusieurs données dynamiques dans un item d'une listview
    Par Rohan21 dans le forum Composants graphiques
    Réponses: 2
    Dernier message: 02/08/2014, 16h50
  2. Ajout dynamique dans un GridView
    Par anto2b dans le forum Android
    Réponses: 4
    Dernier message: 28/11/2012, 18h47
  3. Réponses: 4
    Dernier message: 17/09/2008, 18h05
  4. Ajout de colonne 'Action' dans GridView
    Par Elwe31 dans le forum ASP.NET
    Réponses: 1
    Dernier message: 10/06/2008, 11h10
  5. Colonnes dynamiques dans Rave report
    Par omarkrachni dans le forum Rave
    Réponses: 1
    Dernier message: 10/05/2005, 18h33

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