zoukankan      html  css  js  c++  java
  • [转] polymorphic databinding solutions

    原文链接: http://ayende.com/blog/1558/polymorphic-databinding-solutions 

    Let us assume that you have the following class hierarchy:

     

    Now, what do you think the result of this code will be?

    BindingList<Animal> animals = new BindingList<Animal>();
    
    animals.Add(new Dog());
    
    animals.Add(new Cat());
    
    GridView gridView = new GridView();
    
    gridView.DataSource = animals;
    
    gridView.DataBind();
    

      

    Ten points goes to the lady on the right that said that it will produce the following error:

    Unhandled Exception: System.Reflection.TargetInvocationException: Property accessor 'Name' on object 'AnimalDesc.Cat' threw the following exception:'Object does not match target type.' ---> System.Reflection.TargetException: Object does not match target type.
    

      

    The reason for this bug is that the TypeDescriptors in .Net are not aware of polymorphism. Even though both Cat and Dog inherit from Animal and has a Name property, and that the list that I passed to the DataSource is BindingList<T>, the TypeDescriptor only looks at the first item in the list, and uses it to describe all types in the list. This can cause problems when the collection that you pass to the GridView contains an inheritance hierarchy.

    After butting my head against this issue for too long, I finally came up with this solution:

    public class AnimalTypeDescriptionProvider : TypeDescriptionProvider
    
    {
    
        public AnimalTypeDescriptionProvider() 
    
            :base(TypeDescriptor.GetProvider(typeof(Animal)))
    
        {
    
        }
    
     
    
        public override Type GetReflectionType(Type objectType, object instance)
    
        {
    
            return base.GetReflectionType(typeof(Animal), instance);
    
        }
    
     
    
        public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
    
        {
    
            return base.GetTypeDescriptor(typeof(Animal), instance);
    
        }
    
       
    
        public static void Register()
    
        {
    
            TypeDescriptor.AddProvider(new AnimalTypeDescriptionProvider(), typeof(Animal));
    
        }
    
    }
    

      

    Then, I call the AnimalTypeDescriptionProvider.Register(); method in the start of the application.

    What this does is it lies to the data binding infrastructure, and tells them that any type that inherits from Animal is actually an Animal, and should be treated appropriately.

    This solution is good enough for now, but it will prevent me from databinding a list of Dogs, for instance.

  • 相关阅读:
    ECharts学习总结(四):echarts的实例方法
    ECharts学习总结(三):ECharts图表对象的初始化(init)详解以及注意事项
    ECharts学习总结(二):标签式单文件引入echarts的方法
    ECharts学习总结(一):ECharts的第一个图表
    Eclispe最常用的几个快捷键
    javascript数组去重的4个方法(转)
    数据库主键设计之思考(转)
    数据库插入数据返回当前自增主键ID值的方法
    Node.js制作图片下载爬虫的一般步骤
    Node.js mzitu图片批量下载爬虫1.00
  • 原文地址:https://www.cnblogs.com/crazyghostvon/p/ICustomTypeDescriptor_TargetInvocationException.html
Copyright © 2011-2022 走看看