我会扩展Marc Gravels的有用示例,以通用的方式查看嵌套对象。但是System抛出System.Reflection.TargetException。
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
public class Author
{
public string LastName { get; set; }
public string FirstName { get; set; }
}
public class BookDetails
{
public string Title { get; set; }
public int TotalRating { get; set; }
public int Occurrence { get; set; }
public Author Author { get; set; }
}
//public class MyBindingSource<T> : BindingSource
class MyList<T> : List<T>, ITypedList
{
public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
{
var origProps = TypeDescriptor.GetProperties(typeof(T));
List<PropertyDescriptor> newProps = new List<PropertyDescriptor>(origProps.Count);
foreach (PropertyDescriptor prop in origProps)
{
var childProps = TypeDescriptor.GetProperties(prop.GetType());
if ((childProps.Count == 0) || isSimpleType(prop))
{
newProps.Add(prop);
}
else
{
foreach (PropertyDescriptor childProp in childProps)
{
newProps.Add(new MyPropertyDescriptor(prop, childProp));
}
}
}
return new PropertyDescriptorCollection(newProps.ToArray());
}
private static bool isSimpleType(PropertyDescriptor prop)
{
if (prop.PropertyType.BaseType == typeof(ValueType)) return true;
if (prop.PropertyType == typeof(string)) return true;
if (prop.PropertyType.BaseType != typeof(Object)) return true;
return false;
}
public string GetListName(PropertyDescriptor[] listAccessors)
{
return "";
}
}
class MyPropertyDescriptor : PropertyDescriptor
{
private static readonly Attribute[] nix = new Attribute[0];
private readonly PropertyDescriptor parent;
private readonly PropertyDescriptor child;
public MyPropertyDescriptor(PropertyDescriptor parent, PropertyDescriptor child)
: base(parent.Name + "." + child.Name, nix)
{
this.parent = parent;
this.child = child;
}
public override object GetValue(object component)
{
return child.GetValue(component);
}
public override Type PropertyType
{
get { return child.PropertyType; }
}
public override bool IsReadOnly
{
get { return true; }
}
public override void SetValue(object component, object value)
{
throw new NotSupportedException();
}
public override void ResetValue(object component)
{
throw new NotSupportedException();
}
public override bool CanResetValue(object component)
{
return false;
}
public override Type ComponentType
{
get { return parent.ComponentType; }
}
public override bool ShouldSerializeValue(object component)
{
return false;
}
}
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
var author1 = new Author() { FirstName = "Victor", LastName = "Hugo" };
var author2 = new Author() { FirstName = "Moore", LastName = "Thomas" };
var data = new MyList<BookDetails> {
new BookDetails { Title = "abc", TotalRating = 3, Occurrence = 2, Author = author1 },
new BookDetails { Title = "def", TotalRating = 3, Occurrence = 2, Author = author2 },
new BookDetails { Title = "ghi", TotalRating = 3, Occurrence = 2, Author = author1 },
new BookDetails { Title = "jkl", TotalRating = 3, Occurrence = 2, Author = author2 },
};
Application.Run(new Form
{
Controls = {
new DataGridView {
Dock = DockStyle.Fill,
DataSource = data
}
}
});
}
}
答案 0 :(得分:1)
您应该将prop.GetType()
更改为prop.PropertyType
。
答案 1 :(得分:0)
我自己找到了解决方案:
错误发生在MyPropertyDescriptor中!
校正:
class MyPropertyDescriptor : PropertyDescriptor
{
private static readonly Attribute[] nix = new Attribute[0];
private readonly PropertyDescriptor parent;
private readonly PropertyDescriptor child;
public MyPropertyDescriptor(PropertyDescriptor parent, PropertyDescriptor child)
: base(parent.Name + "." + child.Name, nix)
{
this.parent = parent;
this.child = child;
}
public override object GetValue(object component)
{
var temp = parent.GetValue(component);
if (temp == null) return null;
var temp2 = child.GetValue(temp);
return temp2;
}
public override Type PropertyType
{
get { return child.PropertyType; }
}
public override bool IsReadOnly
{
get { return true; }
}
public override void SetValue(object component, object value)
{
throw new NotSupportedException();
}
public override void ResetValue(object component)
{
throw new NotSupportedException();
}
public override bool CanResetValue(object component)
{
return false;
}
public override Type ComponentType
{
get { return parent.ComponentType; }
}
public override bool ShouldSerializeValue(object component)
{
return false;
}
}