2012-01-30 15 views
12

ho avuto List<Object> dove il oggetto ha un sacco di bambino List<Object> circa 4-6 livelli.Il modo migliore per convertire Lista <Object> a ObservableCollection <Object>

Ora devo legarlo a WPF TreeView ... :(

Quale il modo migliore per convertirlo in ObservableCollection<Object> è?

+1

Perché non basta renderli 'ObservableCollection ' in primo luogo? Quando si lavora con WPF, è importante ottenere il livello dati corretto, e se si sta visualizzando un elenco che può cambiare nell'interfaccia utente, si dovrebbe sempre usare un 'ObservableCollection' invece di un 'Elenco' – Rachel

+0

@Rachel corretto. Il primo posto sono i servizi di RIA. Non so se è possibile farlo ... – Terminador

risposta

4

Una parte della risposta è utilizzare Reactive Extensions (Rx). Puoi ottenerlo da NuGet ed è sviluppato da Microsoft. Con l'aiuto di esso si può semplicemente dire: myListCollection.ToObservable();

Se le vostre collezioni bambino sono sempre in un nodo con lo stesso nome che si potrebbe usare un while(item.Collection != null || item.Collection.Count == 0) e mettere il ToObservable() all'interno del ciclo

+0

Questo è un tale overkill –

18

Supponendo che vuoi dire ObservableCollection<T>, se si voleva direttamente il List al ObservableCollection così come sono, basta utilizzare il costruttore:

var oc = new ObservableCollection<Object>(yourListOfObject); 

Ora, se hai intenzione di svolgere ciascuno di questi, si avrebbe bisogno di fare un po 'wor k per comprimerli in un singolo ObservableCollection<T>.

+0

Se ho creato una classe pubblica chiamata 'Computer' e ho un getter-setter' Name' di una stringa pubblica al suo interno per il mio OC, e quindi ho un 'Elenco lstComputers', mi dice che '' non può convertire da 'System.Collections.Generic.List ' a 'System.Collections.Generic.List ' '. – vapcguy

+0

In realtà ho scoperto come farlo. Non puoi avere tipi non corrispondenti. – vapcguy

1

Presumo che tu stia parlando di ObservableCollection. Per rispondere è sufficiente, è possibile utilizzare il ctor:

List<Object> myList = GetList(); 
new ObservableCollection<Object>(myList); 

Tuttavia, penso che ci sia un po 'di lavoro da fare in termini di organizzazione delle informazioni in modo gerarchico.

+0

Pensi che funzionerà per tutti i bambini Elenco ? – Terminador

+1

L'elenco non è un uso comune di generici. Inizia con una recensione di generici qui: http://stackoverflow.com/questions/155260/what-is-the-syntax-within-c-sharp –

+0

Inoltre, ecco un buon post sul blog ho cercato su Google solo i dettagli vincolanti gerarchici dati a un TreeView WPF: http://www.mattlong.com.au/?p=37 –

1

vuoi dire ObservableCollection? Se si desidera che il livello figlio Lists sia osservabile, sarà necessario attraversare l'albero e modificare gli elementi secondo necessità oppure aggiungere separatamente ciascun oggetto per iniziare.

3

a patto di avere una classe nodo definito in questo modo:

public class Node 
{ 
    public ICollection<Node> Children { get; set; } 
} 

È possibile utilizzare la ricorsione per convertire List<Node> collezioni, a qualsiasi livello di profondità:

public static ObservableCollection<Node> ToObservableRecursive(ICollection<Node> nodes) 
{ 
    foreach (Node node in nodes) 
     if (node.Children != null) 
      node.Children = ToObservableRecursive(node.Children); 

    return new ObservableCollection<Node>(nodes); 
} 
+0

È molto utile! Grazie! – Terminador

+0

Se ho creato una classe pubblica chiamata 'Computer' e ho un getter-setter' Name' di una stringa pubblica al suo interno per il mio OC, e poi ho un 'Elenco lstComputers', mi dice che' 'non posso convertire da 'System. Collections.Generic.List 'a' System.Collections.Generic.List '' – vapcguy

+0

In realtà ho scoperto come farlo. Non puoi avere tipi non corrispondenti. – vapcguy

0

Non si può fare una delle soluzioni elencato qui fino a quando i tuoi tipi sono gli stessi! Se il tuo elenco o ICollection o IEnumerable è di tipo , ad esempio, ma il tuo ObservableCollection deve essere di tipo Nodes o Computers o altro, devi prima ottenere l'Elenco in quel tipo! Ho sprecato così tanto tempo su queste altre false "soluzioni" semplificate che NON sono soluzioni perché non spiegano questo o tengono conto di questo fattore.

dire che questo è il tuo ObservableCollection:

public class Computer 
{ 
    public string Name { get; set; } 
} 

piuttosto standard, giusto? Probabilmente finirai per sostituire Computer con qualsiasi numero di cose in un numero qualsiasi di progetti.

Se poi si ottiene un elenco di nomi di computer in un List<string> chiamato lstComputers, non si può semplicemente convertire che l'utilizzo di:

var oc = new ObservableCollection<Computer>(lstComputers); 

Si dirà i tipi di non corrispondono e non possono essere convertiti da uno all'altro perché stai cercando di spingere un List<string> in un ObservableCollection<Computer>. Piolo quadrato in un buco rotondo.

Invece, nella funzione per ottenere i nomi dei computer, è necessario aggiungere tutti "speciali-like":

public static List<Computer> NetworkComputers() 
{ 
    List<Computer> lstComputers = new List<Computer>(); 
    DirectoryEntry root = new DirectoryEntry("WinNT:"); 
    foreach (DirectoryEntry computers in root.Children) 
    { 
     foreach (DirectoryEntry computer in computers.Children) 
     { 
      if (computer.Name != "Schema" && computer.SchemaClassName == "Computer") 
      { 
       lstComputers.Add(new Computer() { Name = computer.Name }); 
      } 
     } 
    } 
} 

Solo perché abbiamo usato quella linea lstComputers.Add(new Computer() { Name = computer.Name }); e stanno tornando alla List<Computer> e non List<string> può ora lo inseriamo nel nostro ObservableCollection<Computer>.

Se vi siete persi la barca e non si può fare in questo modo fin dall'inizio, questa discussione parla di altri modi si potrebbe essere in grado di fare la vostra conversione: convert a list of objects from one type to another using lambda expression

Quindi, una volta che lo avete in un List<Computer> , solo allora puoi fare:

List<Computer> lstComputers = NetworkComputers(); 
var oc = new ObservableCollection<Computer>(lstComputers); 
Problemi correlati