在 PropertyGrid 中为我无法修改的类型使用自定义编辑器

Use a custom editor in a PropertyGrid for a type I cannot modify

在我的应用程序中,我有一个对象,我想使用 PropertyGrid 编辑它的属性。对于大多数属性,这工作正常。现在这个对象包含 List<string> 类型的 属性。编辑此 属性 时出现错误,因为 string 没有合适的构造函数。

基本上这与this question中描述的情况相同。

不幸的是我不能从那里使用 answer 因为我不能修改我的对象的代码,所以将 Editor 属性应用到 属性 不是一个选项。这里有其他使用自定义编辑器的方法吗?

由于您无法更改您的 class 的代码,您可以在 运行 时为您的 class 注册一个新的类型描述符以提供自定义类型描述。

使用 AssociatedMetadataTypeTypeDescriptionProvider you can create a type descriptor provider for your class that uses a metadata class to provide type description. Then you can register the provider using TypeDescriptor.AddProvider.

例子

假设您无法更改其代码的 class 是这样的:

public class MyClass
{
    public MyClass()
    {
        List = new List<string>();
    }
    public string Name { get; set; }
    public List<string> List { get; set; }
}

要解决这个问题,您应该定义另一个具有相同属性的class,并用您喜欢的属性装饰这些属性,包括编辑器和转换器属性:

public class MyClassMetadata
{
    [DisplayName("Name Property")]
    public string Name { get; set; }

    [Editor(@"System.Windows.Forms.Design.StringCollectionEditor," +
        "System.Design, Version=2.0.0.0, Culture=neutral, " + 
        "PublicKeyToken=b03f5f7f11d50a3a",
        typeof(System.Drawing.Design.UITypeEditor))]
    public List<string> List { get; set; }
}

然后在显示原始 class 之前,为原始 class 注册一个新的类型描述符提供程序,其中 returns 使用我们创建的元数据 class 元数据:

private void Form1_Load(object sender, EventArgs e)
{
    var provider = new AssociatedMetadataTypeTypeDescriptionProvider(typeof(MyClass),
        typeof(MyClassMetadata));
    TypeDescriptor.AddProvider(provider, typeof(MyClass));
    this.propertyGrid1.SelectedObject = new MyClass();
}

我想您已经从 first link:

中获得了 CsvConverter
public class CsvConverter : TypeConverter
{
    // Overrides the ConvertTo method of TypeConverter.
    public override object ConvertTo(ITypeDescriptorContext context,
       CultureInfo culture, object value, Type destinationType)
    {
        List<String> v = value as List<String>;
        if (destinationType == typeof(string))
        {
            return String.Join(",", v.ToArray()); 
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
}