将类型描述符添加到所有List <t>以获取属性网格扩展的通用实现?</t>

时间:2014-12-19 16:54:30

标签: c# winforms generics propertygrid typedescriptor

我为集合定义了一个自定义ExpandableObjectConverter

internal class ExpandableCollectionConverter : ExpandableObjectConverter
{
    public override PropertyDescriptorCollection GetProperties(
        ITypeDescriptorContext context, object value, Attribute[] attributes)
    {
        //implementation that returns a list of property descriptors,
        //one for each item in "value"
    }
}

并且还有一个名为ExpandableObjectManager的代理类,它本质上是这样做的:

TypeDescriptor.AddAttributes(type,
  new TypeConverterAttribute(typeof(ExpandableCollectionConverter)));

使用此方法:

public static class ExpandableObjectManager
{
    public static void AddTypeDescriptor(Type tItem)
    {
        //eventually calls TypeDescriptor.AddAttributes
    }
}

是否可以添加类型描述符,以便所有通用List<T>都可以在属性网格中展开?例如,给定一个简单的Employee类:

class Employee
{
    public string Name { get; set; }
    public string Title { get; set; }
    public DateTime DateOfBirth { get; set; }
}

我可以做到这一点(它有效,但只适用于List<Employee>):

ExpandableObjectManager.AddTypeDescriptor(typeof(List<Employee>));

我想涵盖所有T,而不仅仅是Employee,而不必为每个可能的类写一行。我试过这个 - 没有工作:

ExpandableObjectManager.AddTypeDescriptor(typeof(List<>));

TL; DR:在属性网格中设置为SelectedObject时列表的默认视图:

enter image description here

预期结果:

enter image description here

无需为List<Employee>添加类型描述符,而是为所有List<T>添加一些通用处理程序。

1 个答案:

答案 0 :(得分:2)

编辑:我增加了第三种可能性。

我认为这些都不是很好的解决方案,但这里有三种可能性:

将TypeConverterAttribute添加到泛型类型实现的接口。这里的缺点是你可能没有精确地达到目标类型,但它比选项2更好,因为它更专注于你想要的类型。

TypeDescriptor.AddAttributes(typeof(IList), new
    TypeConverterAttribute(typeof(ExpandableCollectionConverter)));

将TypeConverterAttribute添加到object类型。缺点是,这将使您的类型转换器成为项目中所有类型的类型转换器。

TypeDescriptor.AddAttributes(typeof(object), new
    TypeConverterAttribute(typeof(ExpandableCollectionConverter)));

创建自己的列表类型,该类型继承自List<>并让它在静态构造函数中注册自己

public class CustomList<T> : List<T>
{
    static CustomList()
    {
        TypeDescriptor.AddAttributes(typeof(CustomList<T>), new TypeConverterAttribute(typeof(ExpandableCollectionConverter)));
    }
}