Pergunta

Eu tenho uma lista de objeto personalizado, que consistem em uma lista personalizada.

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

class friend{
  string name;
  string address;
}

I'trying para vincular uma lista desses objetos para um GridView ea grade deve criar para cada amigo uma coluna e escreva o nome nele. Se algumas pessoas têm o mesmo frined a grade não deve criar uma coluna separada, mas usar o já existente. Você sabe o que eu quero dizer. (As classes são apenas algumas classes de amostra para simplificar meu caso)

Existe uma maneira de personalizar dinamicamente a ligação?

posso alterar as definições de classe e assim por diante, se eles precisam para herdar de algumas interfaces ou assim por diante.

Eu pesquisei muito, mas nenhum exemplo realmente parecia cobrir este caso.

Poderia o uso de um objectSourceControl resolver o meu problema de alguma forma?

Update:

Para dar mais algumas informações: No final, eu tenho uma lista de pessoas, enquanto cada pessoa na lista tem uma lista de amigos.

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

A tabela deve ter colunas para cada amigo e as linhas são a pessoa. Quando uma pessoa tem um amigo uma cruz (ou qualquer outro) precisa ser colocado na grade.

friend1 friend2
   x              peter
   x       x      adam

No momento a interceptar o evento RowDataBound e desde que a ligação só cria as linhas com os nomes e não as colunas, porque a única propriedade na minha pessoa objeto é o nome. Existe uma maneira de forçar a ligação a olhar através da lista de propriedade na pessoa objetos e criar uma coluna para cada um deles.

Foi útil?

Solução

Eu era capaz de resolver isso usando um DataTable como sua fonte de dados para o Grid. Eu não gosto da idéia de se mover de um objeto limpa agradável a um DataTable, mas fornece suporte para a ligação dinâmica que você precisa. Eu modifiquei o seu amigo objeto de ter alguns construtores. Isso me permitiu limpeza a declaração de código estático, mas pode não ser necessário em seu implmentation.

A idéia básica é que você vai passar por todos os amigos, adicione seu nome como um DataColumn em um DataTable, em seguida, preencha os dados de todos os objetos pessoa e seus respectivos amigos. Isto poderia provavelmente ser escrito para o trabalho em uma única iteração do objeto allPerson mas preferi duas iterações para tornar o código mais fácil de ler.

A solução é escrito para c # 3.5, mas poderia ser convertida para versões mais antigas, alterando a declaração de dados estáticos. Espero que isso ajude.

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

Edit: I esqueceu de acrescentar como isso é renderizado.

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

Outras dicas

Parece que você está tentando exibir uma matriz / tabela de referência cruzada no GridView. Você pode achar que é mais fácil para agarrar sua recuperar seus dados em um formato mais compatível para isso. Você poderia considerar a escrever uma consulta de referência cruzada, se você estiver usando o servidor SQL.

Se você precisa trabalhar com os objetos na sua forma actual, Criando uma lista mesclada de amigos antes de iniciar também poderia ajudar, fornecendo a lista de colunas. Você poderia, então, ligar a cada coluna para uma chamada de função que poderia tentar encontrar a pessoa coluna na lista de linhas amigo.

Não bonito, mas poderia trabalhar ...

Tenha um olhar para a minha resposta a uma similar 'aninhados ligação' questão aqui .

Você também pode apenas usar o manipulador de eventos RowDataBound fazer ligações complexas.

use o seguinte:

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top