在PropertyGrid中使用自定义编辑器,以获取无法修改的类型

时间:2018-04-19 15:06:28

标签: c# .net winforms propertygrid

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

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

不幸的是我无法使用answer,因为我无法修改对象的代码,因此将Editor属性应用于属性不是一种选择。还有其他方法可以在这里使用自定义编辑器吗?

1 个答案:

答案 0 :(得分:1)

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

使用AssociatedMetadataTypeTypeDescriptionProvider,您可以为您的类创建一个类型描述符提供程序,它使用元数据类来提供类型描述。然后,您可以使用TypeDescriptor.AddProvider注册提供商。

示例

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

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

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

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; }
}

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

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);
    }
}