2011-02-04 56 views
1

这是我最好程度马克砾石的有用实例中一种通用的方法,以查看嵌套对象Marc Gravels's answer的WinForms的DataGridView:绑定对象具有嵌套的对象属性(膨胀列)

的变化。但是系统抛出一个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

我找到了解决办法由自己:

错误是在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; 
    } 
} 
1

你应该改变prop.GetType()prop.PropertyType

相关问题