这是一个基于@PrepucioArgentino 答案的版本,它更好地处理集合中的复杂类型以及结构。您还可以根据名称(在整个结构中)忽略属性。但通常你会想在那里传递一个空列表。
public static class TreeNodeHelper
{
public static void PrintProperties(TreeNode parentNode, object obj, int indent, TreeView treeView, ICollection<string> ignoredPropertyNames)
{
string indentString = new string(' ', indent); // used for debugging
if (obj == null)
return;
var objType = obj.GetType();
var properties = objType.GetProperties()
.Where(x => !ignoredPropertyNames.Contains(x.Name))
.ToList();
foreach (var property in properties)
{
if (property.Name.ToUpper().Contains("DiagMessage".ToUpper()))
{
// TODO rem test code
}
var propValue = new object();
if (property.CanRead)
propValue = property.GetValue(obj, null);
if (IsSimpleType(property.PropertyType))
{
Debug.WriteLine("{0}{1}:", indentString, property.Name);
if (parentNode != null)
{
parentNode.Nodes.Add(property.Name,
$"{property.Name}: {(propValue != null ? propValue.ToString() : string.Empty)}");
}
else
{
treeView.Nodes.Add(property.Name,
$"{property.Name}: {(propValue != null ? propValue.ToString() : string.Empty)}");
}
}
else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
{
TreeNode collectionRootNode;
if (parentNode != null)
{
collectionRootNode = parentNode.Nodes.Add(property.Name, property.Name);
}
else
{
collectionRootNode = treeView.Nodes.Add(property.Name, property.Name);
}
Debug.WriteLine("{0}{1}:", indentString, property.Name);
var enumerable = (IEnumerable)propValue;
var count = 0;
foreach (var child in enumerable)
{
count++;
if (!IsSimpleType(child.GetType()))
{
var entryRootNode = collectionRootNode.Nodes.Add($"{property.Name}[{count}]",
$"{property.Name}[{count}]");
PrintProperties(entryRootNode, child, indent + 2, treeView, ignoredPropertyNames);
}
else
{
collectionRootNode.Nodes.Add($"{property.Name}[{count}]", $"{property.Name}[{count}]: {child}");
}
}
}
else
{
TreeNode node;
if (parentNode != null)
{
node = parentNode.Nodes.Add(property.Name, property.Name);
}
else
{
node = treeView.Nodes.Add(property.Name, property.Name);
}
PrintProperties(node, propValue, indent + 2, treeView, ignoredPropertyNames);
}
}
}
public static bool IsSimpleType(Type type)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
// nullable type, check if the nested type is simple.
return IsSimpleType(type.GetGenericArguments()[0]);
}
return type.IsPrimitive
|| ((IList)new[]
{
// Structs that are 'simple types', expand on this when needed.
typeof(DateTime),
typeof(DateTimeOffset),
typeof(TimeSpan),
typeof(Guid)
}).Contains(type)
|| type.IsEnum
|| type == typeof(string)
|| type == typeof(decimal);
}
}
TreeNodeHelper.PrintProperties(null, firstMotor, 0, treeView1, new List<string>(new[]{ "Creator", "PlcTag", "PlcComponentCreationInfo" }));