将 List<Object> 转换为 ObservableCollection<Object> 的最佳方法

Posted

技术标签:

【中文标题】将 List<Object> 转换为 ObservableCollection<Object> 的最佳方法【英文标题】:The best way to convert List<Object> to ObservableCollection<Object> 【发布时间】:2012-02-22 13:49:37 【问题描述】:

我有 List&lt;Object&gt;,其中 Object 有很多孩子 List&lt;Object&gt; 大约 4-6 级。

现在我必须将它绑定到 WPF TreeView... :(

将其转换为ObservableCollection&lt;Object&gt;最佳方式是?

【问题讨论】:

为什么不首先让他们ObservableCollection&lt;object&gt;?使用 WPF 时,正确设置数据层很重要,如果您曾经在 UI 中显示可以更改的列表,则应始终使用 ObservableCollection 而不是 List @Rachel 正确。第一名是 RIA 服务。不知道能不能做到…… 【参考方案1】:

假设您的意思是ObservableCollection&lt;T&gt;,如果您希望将List 直接转换为ObservableCollection,只需使用构造函数:

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

现在,如果您想放松其中的每一个,您需要做一些工作将它们折叠成一个 ObservableCollection&lt;T&gt;

【讨论】:

如果我创建了一个名为 Computer 的公共类并在里面为我的 OC 有一个公共字符串 Name getter-setter,然后我有一个 List&lt;string&gt; lstComputers,它告诉我我 @987654329 @. 其实我知道怎么做。不能有不匹配的类型。【参考方案2】:

部分答案是使用响应式扩展 (Rx)。您可以从 NuGet 获得它,它是由 Microsoft 开发的。借助它,您可以简单地说:myListCollection.ToObservable();

如果您的子集合始终位于同名节点中,您可以使用 while(item.Collection != null || item.Collection.Count == 0) 并将 ToObservable() 放入循环中

【讨论】:

这太过分了【参考方案3】:

假设你有一个这样定义的节点类:

public class Node

    public ICollection<Node> Children  get; set; 

您可以使用递归来转换List&lt;Node&gt; 集合,在任何深度级别:

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

【讨论】:

非常好用!谢谢! 如果我创建了一个名为 Computer 的公共类并在里面为我的 OC 有一个公共字符串 Name getter-setter,然后我有一个 List&lt;string&gt; lstComputers,它告诉我我 @987654327 @ 其实我知道怎么做。不能有不匹配的类型。【参考方案4】:

我假设您在谈论 ObservableCollection。简单来说,可以使用ctor:

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

但是,我认为在分层组织信息方面还有一些工作要做。

【讨论】:

List 不是泛型的常见用法。从这里开始回顾泛型:***.com/questions/155260/… 此外,这是一篇很好的博文,我刚刚在 Google 上搜索到了将分层数据绑定到 WPF TreeView 的详细信息:mattlong.com.au/?p=37【参考方案5】:

你的意思是ObservableCollection?如果您希望子级别 Lists 也可观察,那么您将需要遍历树并根据需要更改项目或单独添加每个项目。

【讨论】:

【参考方案6】:

在您的类型相同之前,您不能执行此处列出的任何解决方案!例如,如果您的列表或 ICollection 或 IEnumerable 是 string 类型,但您的 ObservableCollection 需要是 NodesComputers 或其他类型,则您必须首先将列表放入该类型!我在其他那些不是解决方案的虚假、简化的“解决方案”上浪费了很多时间,因为它们没有解释这一点,也没有考虑到这个因素。

说这是你的ObservableCollection

public class Computer

    public string Name  get; set; 

相当标准,对吧?您最终可能会在任意数量的项目中用任意数量的东西替换 Computer

如果您随后在名为 lstComputersList&lt;string&gt; 中获得计算机名称列表,则不能仅使用以下方法进行转换:

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

它会说您的类型不匹配并且无法从一种转换到另一种,因为您正试图将List&lt;string&gt; 推入ObservableCollection&lt;Computer&gt;。圆孔中的方钉。

相反,在您获取计算机名称的函数中,您必须将它们全部添加为“特殊类”:

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

仅因为我们使用了那行 lstComputers.Add(new Computer() Name = computer.Name ); 并且返回了 List&lt;Computer&gt; 而不是 List&lt;string&gt;,我们现在才能将它放入我们的 ObservableCollection&lt;Computer&gt;

如果您错过了这艘船并且不能从一开始就这样做,此线程将讨论您可能能够进行转换的其他方式: convert a list of objects from one type to another using lambda expression

因此,一旦您将其保存在 List&lt;Computer&gt; 中,您就可以这样做:

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

【讨论】:

以上是关于将 List<Object> 转换为 ObservableCollection<Object> 的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

将 List<object> 转换为 Dictionary<propertyname,propertyvalue>

将 GraphTraversal<Vertex, Map<Object, List>> 转换为 Java8 流

如何在 C# 中将 List<object> 转换为 Hashtable?

使用点分隔符将 List 转换为 String 到 Map<String, Object>

如何将map<string list<>>转换成城map<string,object>

如何将Object转换为字节数组(一个对象为List )