2012-01-30 37 views
12

Tôi đã có List<Object> nơi Object có rất nhiều Childs List<Object> khoảng 4-6 cấp.Cách tốt nhất để chuyển đổi Danh sách <Object> để ObservableCollection <Object>

Bây giờ tôi phải ràng buộc nó vào WPF TreeView ... :(

nào cách tốt nhất để chuyển đổi nó thành ObservableCollection<Object> là?

+1

Tại sao không chỉ đặt chúng là 'ObservableCollection ' ở nơi đầu tiên? Khi làm việc với WPF, điều quan trọng để có được lớp dữ liệu là đúng và nếu bạn đang hiển thị danh sách có thể thay đổi trong giao diện người dùng, bạn nên luôn sử dụng 'ObservableCollection' thay vì' List' – Rachel

+0

@Rachel Correct. Địa điểm đầu tiên là RIA Services. Tôi không biết nếu nó có thể làm điều đó ... – Terminador

Trả lời

4

Một phần của câu trả lời là sử dụng Tiện ích mở rộng phản ứng (Rx). Bạn có thể lấy nó từ NuGet và nó được phát triển bởi Microsoft. Với sự giúp đỡ của nó, bạn chỉ có thể nói: myListCollection.ToObservable();

Nếu bộ sưu tập con của bạn luôn luôn đang ở trong một nút có cùng tên bạn có thể sử dụng một while(item.Collection != null || item.Collection.Count == 0) và đặt ToObservable() trong vòng

+0

Đây là một quá mức cần thiết –

18

Giả sử bạn có nghĩa là ObservableCollection<T>, nếu bạn muốn List trực tiếp đến ObservableCollection như-là, chỉ cần sử dụng constructor:

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

Bây giờ, nếu bạn đang muốn thư giãn mỗi người, bạn sẽ cần phải làm một số wor k để thu gọn chúng thành một đơn ObservableCollection<T>.

+0

Nếu tôi tạo ra một lớp public gọi là 'Computer' và có một chuỗi công khai' Name' getter-setter bên trong đó cho OC của tôi, và sau đó tôi có một 'List lstComputers', nó cho tôi biết tôi không thể chuyển đổi từ 'System.Collections.Generic.List ' thành 'System.Collections.Generic.List ' '. – vapcguy

+0

Thực ra tôi đã tìm ra cách để làm điều đó. Bạn không thể có các loại không phù hợp. – vapcguy

1

Tôi giả sử bạn đang nói về ObservableCollection. Để trả lời đơn giản, bạn có thể sử dụng ctor:

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

Tuy nhiên, tôi nghĩ có một số việc phải làm để tổ chức thông tin theo cấp bậc.

+0

Bạn có nghĩ rằng nó sẽ làm việc cho tất cả các trẻ em Danh sách ? – Terminador

+1

Danh sách không phải là cách sử dụng phổ biến của thuốc generic. Bắt đầu với một đánh giá của generics ở đây: http://stackoverflow.com/questions/155260/what-is-the-syntax-within-c-sharp –

+0

Ngoài ra, đây là một bài đăng blog tốt tôi chỉ googled rằng chi tiết ràng buộc phân cấp dữ liệu đến một TreeView WPF: http://www.mattlong.com.au/?p=37 –

1

Bạn có nghĩa là ObservableCollection? Nếu bạn muốn cấp độ con Lists cũng có thể quan sát được thì bạn sẽ cần phải đi qua cây và thay đổi các mục nếu cần hoặc thêm từng mục riêng để bắt đầu.

3

Giả sử bạn có một lớp nút được xác định như sau:

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

Bạn có thể sử dụng đệ quy để chuyển đổi List<Node> bộ sưu tập, ở bất kỳ mức độ sâu:

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

Nó rất hữu ích! Cảm ơn bạn! – Terminador

+0

Nếu tôi tạo ra một lớp public gọi là 'Computer' và có một chuỗi công khai' Name' getter-setter bên trong cho OC của tôi, và sau đó tôi có một 'List lstComputers', nó cho tôi biết tôi không thể chuyển đổi từ 'System. Collections.Generic.List 'to' System.Collections.Generic.List '' – vapcguy

+0

Thực ra tôi đã tìm ra cách để làm điều đó. Bạn không thể có các loại không phù hợp. – vapcguy

0

Bạn không thể làm bất kỳ trong những giải pháp được liệt kê ở đây cho đến khi các loại của bạn giống nhau! Ví dụ: nếu danh sách hoặc ICollection hoặc IEnumerable của bạn thuộc loại string, nhưng ObservableCollection cần phải thuộc loại Nodes hoặc Computers hoặc thứ gì đó khác, trước tiên bạn phải đưa Danh sách vào loại đó! Tôi lãng phí quá nhiều thời gian vào những giả mạo khác, "giải pháp" đơn giản không phải là giải pháp bởi vì họ không giải thích điều này hoặc đưa yếu tố này vào tài khoản.

nói đây là ObservableCollection của bạn:

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

Khá chuẩn, phải không? Có thể bạn sẽ phải thay thế Computer bằng bất kỳ số thứ nào trong bất kỳ số dự án nào.

Nếu bạn sau đó nhận được một danh sách các tên máy tính trong một List<string> gọi lstComputers, bạn không thể chỉ chuyển đổi mà sử dụng:

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

Nó sẽ nói loại của bạn là không phù hợp và không thể được chuyển đổi từ một đến khác vì bạn đang cố gắng đẩy một số List<string> vào một số ObservableCollection<Computer>. Hình vuông trong một lỗ tròn.

Thay vào đó, chức năng của bạn để nhận được tên máy tính, bạn phải thêm tất cả "đặc biệt giống như":

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

Chỉ vì chúng tôi sử dụng dòng lstComputers.Add(new Computer() { Name = computer.Name }); và được trả lại List<Computer> và không List<string> thể bây giờ chúng tôi đặt nó vào số ObservableCollection<Computer>.

Nếu bạn bị mất thuyền và không thể làm điều đó như thế này ngay từ đầu, chủ đề này nói về những cách khác bạn có thể có thể làm chuyển đổi của bạn: convert a list of objects from one type to another using lambda expression

Vì vậy, một khi bạn có nó trong một List<Computer> , chỉ khi đó bạn mới có thể thực hiện:

List<Computer> lstComputers = NetworkComputers(); 
var oc = new ObservableCollection<Computer>(lstComputers); 
Các vấn đề liên quan