我一直在寻找最好地完成这项任务的方法,并就此达成了共识。
https://rbrundritt.wordpress.com/2012/01/30/view-object-properties-in-wpf-treeview/
这似乎给了我希望的东西,但当我试图获取线程的对象属性时,我最终得到了stackoverflow异常。因此,objectNode类似乎以递归方式实例化了自己太多次,然后发生了导致堆栈溢出的事情?我不知道该如何解决这个问题,并使它即使在具有许多属性(如线程)的类中也能工作,任何帮助都将非常感谢。
objectNode类如下所示
using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.Reflection;
namespace Server.Host
{
public class ObjectNode
{
#region Private Properties
private string _name;
private object _value;
private Type _type;
#endregion
#region Constructor
public ObjectNode(object value)
{
ParseObjectTree("root", value, value.GetType());
}
public ObjectNode(string name, object value)
{
ParseObjectTree(name, value, value.GetType());
}
public ObjectNode(object value, Type t)
{
ParseObjectTree("root", value, t);
}
public ObjectNode(string name, object value, Type t)
{
ParseObjectTree(name, value, t);
}
#endregion
#region Public Properties
public string Name
{
get { return _name; }
}
public object Value
{
get { return _value; }
}
public Type Type
{
get { return _type; }
}
public ObservableCollection<ObjectNode> Children { get; set; }
#endregion
#region Private Methods
private void ParseObjectTree(string name, object value, Type type)
{
Children = new ObservableCollection<ObjectNode>();
_type = type;
_name = name;
if (value != null)
{
if (value is string && type != typeof(object))
{
if (value != null)
{
_value = "\"" + value + "\"";
}
}
else if (value is double || value is bool || value is int || value is float || value is long || value is decimal)
{
_value = value;
}
else
{
_value = "{" + value.ToString() + "}";
}
}
PropertyInfo[] props = type.GetProperties();
if (props.Length == 0 && type.IsClass && value is IEnumerable && !(value is string))
{
IEnumerable arr = value as IEnumerable;
if (arr != null)
{
int i = 0;
foreach (object element in arr)
{
Children.Add(new ObjectNode("[" + i + "]", element, element.GetType()));
i++;
}
}
}
foreach (PropertyInfo p in props)
{
if (p.PropertyType.IsPublic)
{
if (p.PropertyType.IsClass || p.PropertyType.IsArray || p.PropertyType.IsInterface)
{
if (p.PropertyType.IsArray)
{
try
{
object v = p.GetValue(value, null);
IEnumerable arr = v as IEnumerable;
ObjectNode arrayNode = new ObjectNode(p.Name, arr.ToString(), typeof(object));
if (arr != null)
{
int i = 0, k = 0;
ObjectNode arrayNode2;
foreach (object element in arr)
{
//Handle 2D arrays
if (element is IEnumerable && !(element is string))
{
arrayNode2 = new ObjectNode("[" + i + "]", element.ToString(), typeof(object));
IEnumerable arr2 = element as IEnumerable;
k = 0;
foreach (object e in arr2)
{
arrayNode2.Children.Add(new ObjectNode("[" + k + "]", e, e.GetType()));
k++;
}
arrayNode.Children.Add(arrayNode2);
}
else
{
arrayNode.Children.Add(new ObjectNode("[" + i + "]", element, element.GetType()));
}
i++;
}
}
Children.Add(arrayNode);
}
catch { }
}
else
{
object v = p.GetValue(value, null);
if (v != null)
{
Children.Add(new ObjectNode(p.Name, v, p.PropertyType));
}
}
}
else if (p.PropertyType.IsValueType && !(value is string))
{
try
{
object v = p.GetValue(value, null);
if (v != null)
{
Children.Add(new ObjectNode(p.Name, v, p.PropertyType));
}
}
catch { }
}
}
}
}
#endregion
}
}
因此,可以将TreeView添加到WPF中,如下所示
<TreeView Name="ResultTreeView" BorderThickness="0">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:ObjectNode}"
ItemsSource="{Binding Path=Children}">
<TreeViewItem>
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal" Margin="-10,0,0,0">
<TextBlock Text="{Binding Path=Name}"/>
<TextBlock Text=" : "/>
<TextBlock Text="{Binding Path=Value}"/>
</StackPanel>
</TreeViewItem.Header>
</TreeViewItem>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
然后在我的代码中,我简单地写
private Foo foo = new Foo();
ObservableCollection<ObjectNode> nodes = new ObservableCollection<ObjectNode>();
nodes.Add(new ObjectNode("result", foo));
ResultTreeView.ItemsSource = nodes;
其中Foo可以是任何类。在大多数情况下,它运行良好。但如果我在类中有一个线程,它会抛出一个异常。例如,一个简单的
public class Foo
{
public Foo()
{
Bar = new Thread(Baz);
}
public Thread Bar { get; set; }
private static void Baz()
{
}
}
引发的错误是
“mscorlib.dll中出现类型为“System.StackOverflowException”的未处理异常”
再次,我们非常欢迎任何建议。