我已经快知道了,但是我很难优雅地完成最后一部分。此答案是根据杰里米·汤普森(Jeremy Thompson)提交的答案而更新的。这是我到目前为止所拥有的:
public void SetupTree()
{
var types = Assembly.Load("Data").GetTypes().Where(t => t.IsPublic && t.IsClass);
if (types.Count() > 0)
{
if (treeView_left.Nodes.Count == 0)
{
treeView_left.Nodes.Add(new TreeNode("Structure Data"));
treeView_left.Nodes[0].Nodes.Add(types.First().GetHashCode().ToString(), types.First().Name);
}
foreach (Type type in types)
{
BuildTree(types, type, treeView_left.Nodes[0].Nodes[0]);
}
}
treeView_left.Refresh();
}
private void BuildTree(IEnumerable<Type> types, Type type, TreeNode parentNode)
{
var tempNodes = treeView_left.Nodes.Find(type.BaseType.GetHashCode().ToString(), true);
if (tempNodes.Count() > 0)
{
parentNode = tempNodes[0];
if (tempNodes.Count() != 1)
{
//TODO: warning
}
}
if (parentNode != null)
{
if (treeView_left.Nodes.Find(type.GetHashCode().ToString(), true).Count() == 0)
{
parentNode.Nodes.Add(type.GetHashCode().ToString(), type.Name);
}
foreach (Type t in types.Where(x => x.IsSubclassOf(type)))
{
BuildTree(types, t, parentNode.Nodes[type.GetHashCode().ToString()]);
}
}
}
这会产生我想要的结果,但是我怀疑我正在努力地做一些事情。如果有人能指出最后一部分的更清洁方法,我会推荐它。
最佳答案
我尚未对此进行测试,但是请注意递归调用LoadAllChildren
本身会进行调用。
public void SetupTree()
{
Assembly dataLib = Assembly.Load("Data");
TreeNode theTree = new TreeNode("Assembly Data");
foreach (Type type in dataLib.GetTypes())
{
LoadAllChildren(dataLib, type, theTree);
}
treeView_left.Nodes.Add(theTree); //Optimisation - bind all nodes in one go rather than adding individually
}
private void LoadAllChildren(Assembly dataLib,Type type, TreeNode parentNode)
{
if (type.IsPublic && type.IsClass)
{
TreeNode node = new TreeNode(type.Name);
parentNode.Nodes.Add(node);
var types = dataLib.GetTypes().Where(x => x.IsSubclassOf(type));
foreach (Type t in types)
{
LoadAllChildren(dataLib, t, node);
}
}
}
我希望这足以让您克服困难,随时问Q
当我的PC即将重建时,我不会迅速做出反应:(
关于c# - 从程序集动态生成WinForms TreeView,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15125553/