将 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<Object>
,其中 Object 有很多孩子 List<Object>
大约 4-6 级。
现在我必须将它绑定到 WPF TreeView... :(
将其转换为ObservableCollection<Object>
的最佳方式是?
【问题讨论】:
为什么不首先让他们ObservableCollection<object>
?使用 WPF 时,正确设置数据层很重要,如果您曾经在 UI 中显示可以更改的列表,则应始终使用 ObservableCollection
而不是 List
@Rachel 正确。第一名是 RIA 服务。不知道能不能做到……
【参考方案1】:
假设您的意思是ObservableCollection<T>
,如果您希望将List
直接转换为ObservableCollection
,只需使用构造函数:
var oc = new ObservableCollection<Object>(yourListOfObject);
现在,如果您想放松其中的每一个,您需要做一些工作将它们折叠成一个 ObservableCollection<T>
。
【讨论】:
如果我创建了一个名为Computer
的公共类并在里面为我的 OC 有一个公共字符串 Name
getter-setter,然后我有一个 List<string> 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<Node>
集合,在任何深度级别:
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<string> lstComputers
,它告诉我我 @987654327 @
其实我知道怎么做。不能有不匹配的类型。【参考方案4】:
我假设您在谈论 ObservableCollection。简单来说,可以使用ctor:
List<Object> myList = GetList();
new ObservableCollection<Object>(myList);
但是,我认为在分层组织信息方面还有一些工作要做。
【讨论】:
List 此外,这是一篇很好的博文,我刚刚在 Google 上搜索到了将分层数据绑定到 WPF TreeView 的详细信息:mattlong.com.au/?p=37【参考方案5】:你的意思是ObservableCollection?如果您希望子级别 Lists
也可观察,那么您将需要遍历树并根据需要更改项目或单独添加每个项目。
【讨论】:
【参考方案6】:在您的类型相同之前,您不能执行此处列出的任何解决方案!例如,如果您的列表或 ICollection 或 IEnumerable 是 string
类型,但您的 ObservableCollection
需要是 Nodes
或 Computers
或其他类型,则您必须首先将列表放入该类型!我在其他那些不是解决方案的虚假、简化的“解决方案”上浪费了很多时间,因为它们没有解释这一点,也没有考虑到这个因素。
说这是你的ObservableCollection
:
public class Computer
public string Name get; set;
相当标准,对吧?您最终可能会在任意数量的项目中用任意数量的东西替换 Computer
。
如果您随后在名为 lstComputers
的 List<string>
中获得计算机名称列表,则不能仅使用以下方法进行转换:
var oc = new ObservableCollection<Computer>(lstComputers);
它会说您的类型不匹配并且无法从一种转换到另一种,因为您正试图将List<string>
推入ObservableCollection<Computer>
。圆孔中的方钉。
相反,在您获取计算机名称的函数中,您必须将它们全部添加为“特殊类”:
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<Computer>
而不是 List<string>
,我们现在才能将它放入我们的 ObservableCollection<Computer>
。
如果您错过了这艘船并且不能从一开始就这样做,此线程将讨论您可能能够进行转换的其他方式: convert a list of objects from one type to another using lambda expression
因此,一旦您将其保存在 List<Computer>
中,您就可以这样做:
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>