Pregunta

Tengo una Lista de objetos personalizados, que consiste en una lista personalizada.

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

class friend{
  string name;
  string address;
}

Estoy intentando vincular una lista de estos objetos a un GridView y el Grid debería crear para cada amigo una columna y escribir el nombre en ella. Si algunas personas tienen el mismo borde, la cuadrícula no debería crear una columna separada, sino usar la existente. Sabes a lo que me refiero. (Las clases son solo algunas clases de muestra para simplificar mi caso)

¿Hay alguna forma de personalizar dinámicamente el enlace?

Puedo cambiar las definiciones de clase, etc., si necesitan heredar de algunas interfaces, etc.

Busqué en Google mucho, pero ningún ejemplo realmente parecía cubrir este caso.

¿Podría el uso de un objectSourceControl resolver mi problema de alguna manera?

Actualización:

Para dar más información: Al final tengo una lista de personas, mientras que cada persona en la lista tiene una lista de amigos.

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

La tabla debe tener columnas para cada amigo y las filas son la persona. Cuando una persona tiene un amigo, se debe colocar una cruz (o lo que sea) en la cuadrícula.

friend1 friend2
   x              peter
   x       x      adam

Por el momento, intercepto el evento RowDataBound y dado que el enlace solo crea las filas con los nombres y no las columnas, porque la única propiedad en mi objeto persona es el nombre. ¿Hay alguna manera de obligar al enlace a mirar a través de la Propiedad de lista en los objetos personales y crear una columna para cada uno de ellos?

¿Fue útil?

Solución

Pude resolver esto usando una DataTable como su fuente de datos para Grid. No me gusta la idea de pasar de un objeto limpio agradable a una DataTable, pero proporciona soporte para el enlace dinámico que necesita. Modifiqué tu objeto amigo para tener algunos constructores. Esto me permitió limpiar la declaración del código estático, pero podría no ser necesario en su implicación.

La idea básica es que pasará por todos los amigos posibles, agregará su nombre como DataColumn en una DataTable y luego completará los datos de todos los objetos personales y sus respectivos amigos. Esto probablemente podría escribirse para que funcione en una sola iteración del objeto allPerson, pero preferí dos iteraciones para que el código sea más fácil de leer.

La solución está escrita para c # 3.5 pero podría convertirse para versiones anteriores cambiando la declaración de datos estáticos. Espero que esto ayude.

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;
    }
}

Editar: Olvidé agregar cómo se representa esto.

-------------------------------------------------
| 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     |      |      |     |     |
-------------------------------------------------   

Otros consejos

Parece que está intentando mostrar una matriz / tabla de referencias cruzadas en GridView. Es posible que le resulte más fácil obtener sus datos recuperados en un formato más compatible con esto. Podría considerar escribir una consulta de tabla cruzada si está utilizando el servidor SQL.

Si debe trabajar con los objetos en su forma actual, crear una lista combinada de amigos antes de comenzar también podría ayudar al proporcionar la lista de columnas. Luego, puede vincular a cada columna a una llamada de función que podría intentar encontrar a la persona de la columna en la lista de amigos de las filas.

No es hermoso, pero podría funcionar ...

Eche un vistazo a mi respuesta a una pregunta similar de 'enlace anidado' aquí .

También podría usar el controlador de eventos RowDataBound para realizar enlaces complejos.

usa lo siguiente:

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top