Question

J'ai une liste d'objets personnalisés, qui consiste en une liste personnalisée.

class person{
  string name;
  int age;
  List<friend> allMyFriends;
}

class friend{
  string name;
  string address;
}

J'essaie de lier une liste de ces objets à un GridView et la grille doit créer pour chaque ami une colonne et y écrire le nom. Si certaines personnes ont le même problème, la grille ne doit pas créer de colonne distincte, mais utiliser la colonne existante. Tu sais ce que je veux dire. (Les classes ne sont que quelques exemples de classes pour simplifier mon cas)

Existe-t-il un moyen de personnaliser dynamiquement la liaison?

Je peux modifier les définitions de classe, etc., s'ils doivent hériter de certaines interfaces, etc.

.

J'ai beaucoup cherché sur Google, mais aucun exemple ne semblait vraiment couvrir cette affaire.

L'utilisation d'un objectSourceControl pourrait-elle résoudre mon problème d'une manière ou d'une autre?

Mise à jour:

Pour donner plus d’informations: À la fin, j'ai une liste de personnes, tandis que chaque personne dans la liste a une liste d'amis.

List<person> allPerson = new List<person>();
// fill the list
Grid.DataSource = allPerson;
Grid.DataBind()

La table doit avoir des colonnes pour chaque ami et les lignes sont la personne. Lorsqu'une personne a un ami, une croix (ou autre) doit être placée dans la grille.

friend1 friend2
   x              peter
   x       x      adam

À l'heure actuelle, intercepte l'événement RowDataBound et, étant donné que la liaison crée uniquement les lignes portant les noms, et non les colonnes, car la seule propriété de mon objet personne est le nom. Existe-t-il un moyen de forcer la liaison à parcourir la propriété de liste dans les objets Personne et à créer une colonne pour chacun d'eux.

Était-ce utile?

La solution

J'ai pu résoudre ce problème en utilisant un DataTable comme source de données pour la grille. Je n'aime pas l'idée de passer d'un bel objet propre à un DataTable, mais cela prend en charge la liaison dynamique dont vous avez besoin. J'ai modifié votre objet ami pour avoir quelques constructeurs. Cela m’a permis de nettoyer la déclaration de code statique mais que cela ne serait peut-être pas nécessaire dans votre implémentation.

L'idée de base est que vous allez parcourir tous les amis possibles, ajouter leur nom en tant que DataColumn dans un DataTable, puis renseigner les données de tous les objets Personne et de leurs amis respectifs. Cela pourrait probablement être écrit pour fonctionner dans une seule itération de l'objet allPerson mais j'ai préféré deux itérations pour rendre le code plus facile à lire.

La solution est écrite pour c # 3.5 mais peut être convertie pour les versions antérieures en modifiant la déclaration de données statique. J'espère que cela aide.

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // setup your person object with static data for testing
        List<person> allPerson = new List<person>()
        {
            new person() 
            { 
                name = "Dan", 
                age = 21, 
                allMyFriends = new List<friend>() { new friend("James"), new friend("John"), new friend("Matt") } 
            }, 
            new person() 
            { 
                name = "James", 
                age = 21, 
                allMyFriends = new List<friend>() { new friend("Dan"), new friend("Matt"), new friend("Tom") } 
            }, 
            new person() 
            { 
                name = "John", 
                age = 21, 
                allMyFriends = new List<friend>() { new friend("Dan") } 
            }, 
            new person() 
            { 
                name = "Matt", 
                age = 21, 
                allMyFriends = new List<friend>() { new friend("Dan"), new friend("James") } 
            }, 
            new person() 
            { 
                name = "Tom", 
                age = 21, 
                allMyFriends = new List<friend>() { new friend("James") } 
            }
        };

        System.Data.DataTable dt = new System.Data.DataTable();
        dt.Columns.Add("Name");
        dt.Columns.Add("Age");

        foreach (person p in allPerson)
        {
            // step through each person and look at their friends
            foreach (friend f in p.allMyFriends)
            {
                // look to see if this friend has a column already
                if (!dt.Columns.Contains(f.name))
                {
                    dt.Columns.Add(f.name);
                }
            }
        }

        foreach (person p in allPerson)
        {
            // create the datarow that represents the person
            System.Data.DataRow dr = dt.NewRow();
            dr["Name"] = p.name;
            dr["Age"] = p.age;

            // find the friends and mark them
            foreach (friend f in p.allMyFriends)
            {
                dr[f.name] = "X";
            }

            dt.Rows.Add(dr);
        }

        // fill the list
        this.Grid.DataSource = dt;
        this.Grid.DataBind();

    }
}

public class person
{
    public string name;
    public int age;
    public List<friend> allMyFriends = new List<friend>();
}

public class friend
{
    public string name;
    public string address;

    public friend()
    {

    }

    public friend(string name)
    {
        this.name = name;
    }

    public friend(string name, string address)
    {
        this.name = name;
        this.address = address;
    }
}

Modifier: J'ai oublié d'ajouter comment cela est rendu.

-------------------------------------------------
| Name  | Age | James | John | Matt | Dan | Tom |
-------------------------------------------------
| Dan   | 21  | X     | X    | X    |     |     |
| James | 21  |       |      | X    | X   | X   |
| John  | 21  |       |      |      | X   |     |
| Matt  | 21  | X     |      |      | X   |     |
| Tom   | 21  | X     |      |      |     |     |
-------------------------------------------------   

Autres conseils

On dirait que vous essayez d’afficher une matrice / un tableau croisé dans GridView. Vous trouverez peut-être plus facile de récupérer vos données dans un format plus compatible avec celui-ci. Vous pouvez envisager d'écrire une requête d'analyse croisée si vous utilisez SQL Server.

Si vous devez utiliser les objets dans leur forme actuelle, vous pouvez également créer une liste d’amis fusionnée avant de commencer en fournissant la liste des colonnes. Vous pouvez ensuite lier à chaque colonne un appel de fonction qui pourrait tenter de trouver la personne de la colonne dans la liste d'amis de la rangée.

Pas beau, mais ça pourrait marcher ...

Consultez ma réponse à une question similaire "à liens imbriqués" ici .

Vous pouvez également simplement utiliser le gestionnaire d'événements RowDataBound pour effectuer des liaisons complexes.

utilisez les éléments suivants:

DataBinder.Eval (Container.DataItem, "PPP.PPP")

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top