Domanda

Ho un Elenco di oggetti personalizzati, che consistono in un elenco personalizzato.

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

class friend{
  string name;
  string address;
}

Sto cercando di associare un elenco di questi oggetti a GridView e la griglia dovrebbe creare per ogni amico una colonna e scrivere il nome in essa. Se alcune persone hanno lo stesso aspetto, la griglia non dovrebbe creare una colonna separata, ma utilizzare quella esistente. Sai cosa intendo. (Le classi sono solo alcune classi di esempio per semplificare il mio caso)

C'è un modo per personalizzare dinamicamente l'associazione?

Posso modificare le definizioni delle classi e così via, se devono ereditare da alcune interfacce o così via.

Ho cercato su Google molto, ma nessun esempio sembrava davvero coprire questo caso.

L'uso di objectSourceControl potrebbe risolvere il mio problema in qualche modo?

Aggiornamento:

Per fornire ulteriori informazioni: Alla fine ho un elenco di persone, mentre ogni persona nell'elenco ha un elenco di amici.

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

La tabella dovrebbe contenere colonne per ciascun amico e le righe sono la persona. Laddove una persona abbia un amico, è necessario posizionare una croce (o qualsiasi altra cosa) nella griglia.

friend1 friend2
   x              peter
   x       x      adam

Al momento intercettare l'evento RowDataBound e poiché l'associazione crea solo le righe con i nomi e non le colonne, poiché l'unica proprietà dell'oggetto my person è il nome. C'è un modo per forzare l'associazione a guardare attraverso la proprietà elenco negli oggetti persona e creare una colonna per ognuno di essi.

È stato utile?

Soluzione

Sono stato in grado di risolvere questo problema utilizzando una DataTable come origine dati per la griglia. Non mi piace l'idea di passare da un bel oggetto pulito a una DataTable, ma fornisce supporto per l'associazione dinamica di cui hai bisogno. Ho modificato l'oggetto del tuo amico per avere alcuni costruttori. Questo mi ha permesso di ripulire la dichiarazione del codice statico ma potrebbe non essere necessario nella tua implementazione.

L'idea di base è quella di scorrere tutti i possibili amici, aggiungere il loro nome come DataColumn in una DataTable, quindi inserire i dati per tutti gli oggetti persona e i loro rispettivi amici. Probabilmente questo potrebbe essere scritto per funzionare in una singola iterazione dell'oggetto allPerson, ma ho preferito due iterazioni per rendere più semplice la lettura del codice.

La soluzione è scritta per c # 3.5 ma potrebbe essere convertita per versioni precedenti modificando la dichiarazione dei dati statici. Spero che questo aiuti.

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

Modifica: Ho dimenticato di aggiungere come viene visualizzato.

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

Altri suggerimenti

Sembra che tu stia provando a visualizzare una matrice / tabella a campi incrociati in GridView. Potresti trovare più semplice recuperare i tuoi dati in un formato più compatibile con questo. È possibile prendere in considerazione la possibilità di scrivere una query a campi incrociati se si utilizza SQL Server.

Se devi lavorare con gli oggetti nella loro forma attuale, anche la creazione di un elenco unito di amici prima di iniziare potrebbe essere utile fornendo l'elenco di colonne. È quindi possibile associare ciascuna colonna a una chiamata di funzione che potrebbe tentare di trovare la persona della colonna nell'elenco degli amici delle righe.

Non bello, ma potrebbe funzionare ...

Dai un'occhiata alla mia risposta a una domanda analoga di 'nidificazione vincolante' qui .

Puoi anche usare il gestore di eventi RowDataBound per eseguire associazioni complesse.

usa quanto segue:

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top