2012-01-30 8 views
12

Mam List<Object> gdzie Object ma wiele Childs List<Object> około 4-6 poziomach.Najlepszym sposobem konwersji listy <Object> do ObservableCollection <Object>

Teraz muszę powiązać go z WPF TreeView ... :(

Które najlepszym sposobem aby przekształcić go w ObservableCollection<Object> jest?

+1

Dlaczego nie po prostu uczynić je '' ObservableCollection w pierwszej kolejności? Podczas pracy z WPF ważne jest, aby warstwa danych była poprawna, a jeśli kiedykolwiek wyświetlasz listę, która może się zmienić w interfejsie, zawsze powinieneś używać 'ObservableCollection' zamiast' List' – Rachel

+0

@Rachel Correct. Pierwsze miejsce to usługi RIA. Nie wiem, czy da się to zrobić ... – Terminador

Odpowiedz

4

Jedna część odpowiedzi to użycie rozszerzeń reaktywnych (Rx). Możesz pobrać go z NuGet i jest on opracowany przez firmę Microsoft. Dzięki niemu można po prostu powiedzieć: myListCollection.ToObservable();

Jeśli twoje dziecko kolekcje zawsze są w węźle o tej samej nazwie można użyć while(item.Collection != null || item.Collection.Count == 0) i umieścić ToObservable() wewnątrz pętli

+0

To jest taka przesada –

18

Zakładając znaczy ObservableCollection<T>, jeśli chciał List bezpośrednio do ObservableCollection jak jest, wystarczy użyć konstruktora:

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

teraz, jeśli chcą rozwijać każdy z nich, trzeba by zrobić jakiś wor k, aby zwinąć je w pojedynczy ObservableCollection<T>.

+0

Jeśli utworzyłem publiczną klasę o nazwie 'Komputer' i mam tam publiczny ciąg' Name' getter-setter dla mojego OC, a następnie mam 'List lstComputers', mówi mi, że 'nie mogę przekonwertować z 'System.Collections.Generic.List ' na 'System.Collections.Generic.List ''. – vapcguy

+0

Właściwie to dowiedziałem się, jak to zrobić. Nie możesz mieć niedopasowanych typów. – vapcguy

1

Zakładam, że mówisz o ObservableCollection. Aby odpowiedzieć po prostu, można użyć konstruktor:

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

Myślę jednak, że jest jakaś praca pozostało do zrobienia w zakresie organizowania informacji hierarchicznie.

+0

Czy uważasz, że będzie działać dla wszystkich dzieci Lista ? – Terminador

+1

Lista nie jest powszechnym zastosowaniem generycznych. Zacznij od przeglądu generycznych tutaj: http://stackoverflow.com/questions/155260/what-is-the-syntax-within-c-sharp –

+0

Ponadto tutaj jest dobry wpis na blogu Właśnie googled, że szczegóły wiążące hierarchiczne dane do drzewa WPF TreeView: http://www.mattlong.com.au/?p=37 –

1

masz na myśli ObservableCollection? Jeśli chcesz, aby poziom dziecka Lists był obserwowany, musisz przejść drzewo i zmienić elementy w razie potrzeby lub dodać każdy element osobno, aby rozpocząć.

3

Zakładając, że klasa węzeł zdefiniowane tak:

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

Można użyć rekurencji do konwersji List<Node> kolekcje, na każdym poziomie Głębokość:

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

Jest to bardzo przydatne! Dziękuję Ci! – Terminador

+0

Jeśli utworzyłem publiczną klasę o nazwie 'Komputer' i mam tam publiczny ciąg' Name' getter-setter dla mojego OC, a potem mam 'List lstComputers', to mówi mi, że' nie mogę przekonwertować z 'Systemu. Collections.Generic.List 'to' System.Collections.Generic.List '' – vapcguy

+0

Właściwie dowiedziałem się, jak to zrobić. Nie możesz mieć niedopasowanych typów. – vapcguy

0

nie można zrobić żadnej z tych rozwiązań wymienione tutaj, dopóki twoje typy nie będą takie same! Jeśli twoja lista lub ICollection lub IEnumerable jest na przykład typu string, ale Twój ObservableCollection musi być typu Nodes lub Computers lub czymś innym, musisz najpierw uzyskać List do tego typu! Zmarnowałem tak wiele czasu na te inne fałszywe, uproszczone "rozwiązania", które NIE są rozwiązaniami, ponieważ nie wyjaśniają tego lub biorą pod uwagę ten czynnik.

powiedzieć, że to Twój ObservableCollection:

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

dość standardowy, prawda? Prawdopodobnie zastąpiłbyś Computer dowolną liczbą rzeczy w dowolnej liczbie projektów.

Jeśli następnie uzyskać listę nazw komputerów w sposób List<string> nazywa lstComputers, nie można po prostu przekonwertować za pomocą:

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

powie Twoje typy są niedopasowane i nie mogą być przekształcane z jednego do drugiego, ponieważ próbujesz wsunąć List<string> do ObservableCollection<Computer>. Kwadratowy kołek w okrągłym otworze.

Zamiast tego, w swojej funkcji dla uzyskania nazw komputerów, trzeba dodać je wszystkie „special-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 }); 
      } 
     } 
    } 
} 

Tylko dlatego użyliśmy tej linii lstComputers.Add(new Computer() { Name = computer.Name }); i wracają do List<Computer> i nie List<string> puszka teraz umieściliśmy to w naszym ObservableCollection<Computer>.

Jeśli przegapiłeś łódź i nie może zrobić to w ten sposób od samego początku, ten wątek opowiada o innych sposobów, może być w stanie wykonać konwersję: convert a list of objects from one type to another using lambda expression

Więc skoro masz go w List<Computer> , tylko wtedy można zrobić:

List<Computer> lstComputers = NetworkComputers(); 
var oc = new ObservableCollection<Computer>(lstComputers); 
Powiązane problemy