为所有List <T>添加类型描述符,以实现属性网格扩展的通用实现?

Neo*_*isk 5 c# generics propertygrid typedescriptor winforms

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"
    }
}
Run Code Online (Sandbox Code Playgroud)

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

TypeDescriptor.AddAttributes(type,
  new TypeConverterAttribute(typeof(ExpandableCollectionConverter)));
Run Code Online (Sandbox Code Playgroud)

使用此方法:

public static class ExpandableObjectManager
{
    public static void AddTypeDescriptor(Type tItem)
    {
        //eventually calls TypeDescriptor.AddAttributes
    }
}
Run Code Online (Sandbox Code Playgroud)

是否有可能以这样的方式添加类型描述符,即所有泛型List<T>都可以在属性网格中展开?例如,给出一个简单的Employee类:

class Employee
{
    public string Name { get; set; }
    public string Title { get; set; }
    public DateTime DateOfBirth { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

ExpandableObjectManager.AddTypeDescriptor(typeof(List<Employee>));
Run Code Online (Sandbox Code Playgroud)

我想覆盖所有T,不仅仅是Employee,不必为每个可能的类写一行.我试过这个 - 没用:

ExpandableObjectManager.AddTypeDescriptor(typeof(List<>));
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

预期成绩:

在此输入图像描述

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

Gra*_*x32 3

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

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

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

TypeDescriptor.AddAttributes(typeof(IList), new
    TypeConverterAttribute(typeof(ExpandableCollectionConverter)));
Run Code Online (Sandbox Code Playgroud)

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

TypeDescriptor.AddAttributes(typeof(object), new
    TypeConverterAttribute(typeof(ExpandableCollectionConverter)));
Run Code Online (Sandbox Code Playgroud)

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

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