PropertyGrid .NET中的TypeConverter重用winforms

时间:2018-03-26 21:25:20

标签: .net propertygrid typeconverter

我想问一下,在PropertyGrid中实现自定义下拉列表时是否可以重用相同的TypeConverter,但是使用不同的项目。考虑使用以下TypeConverter在PropertyGrid中实现2项(dog / cat)下拉列表。

Public Class MyList : Inherits System.ComponentModel.StringConverter
    Public items As String() = New String() {"dog", "cat"} 

    Public Overloads Overrides Function GetStandardValues(ByVal context As System.ComponentModel.ITypeDescriptorContext) As System.ComponentModel.TypeConverter.StandardValuesCollection
        Return New StandardValuesCollection(items)
    End Function

    Public Overloads Overrides Function GetStandardValuesSupported(ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
        Return True
    End Function

    Public Overloads Overrides Function GetStandardValuesExclusive(ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
        Return True
    End Function
End Class

此TypeConverter用作:

<TypeConverter(GetType(MyList))>
Public Class MyDogAndCatList
   ...
End Class

我现在想重用相同的TypeConverter MyList,但是使用不同的列表项。例如。而不是狗/猫,我想使用牛/羊,然后定义复杂的数据类。像这样:

cow_sheep = new MyList({"cow", "sheep"})
<TypeConverter(GetType(cow_sheep)), ...

但是这似乎不可能,因为TypeConverter必须是Class而不能是实例。我想重用TypeConverter,因为我有很多要处理的列表,我不想为每个列表定义一个新的TypeConverter,而几乎所有被覆盖的函数总是相同的。

我知道我可以通过基本转换器构建,然后继承它以简化我的代码。但这仍然意味着要处理100多个不同的类,我肯定认为这不是正确的方法。

有人知道怎么做吗?欢迎任何帮助。提前谢谢。

1 个答案:

答案 0 :(得分:0)

您无法更改TypeConverterAttribute以向其添加内容,但您可以向该属性添加任意数量的自定义属性,因此您可以创建自己的属性来保存自定义数据。

以下是一些示例C#代码:

public class Animals
{
    // both properties have the same TypeConverter, but they use different custom attributes
    [TypeConverter(typeof(ListTypeConverter))]
    [ListTypeConverter(new [] { "cat", "dog" })]
    public string Pets { get; set; }

    [TypeConverter(typeof(ListTypeConverter))]
    [ListTypeConverter(new [] { "cow", "sheep" })]
    public string Others { get; set; }
}

// this is your custom attribute
// Note attribute can only use constants (as they are added at compile time), so you can't add a List object here
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class ListTypeConverterAttribute : Attribute
{
    public ListTypeConverterAttribute(string[] list)
    {
        List = list;
    }

    public string[] List { get; set; }
}

// this is the type converter that knows how to use the ListTypeConverterAttribute attribute
public class ListTypeConverter : TypeConverter
{
    public override bool GetStandardValuesSupported(ITypeDescriptorContext context) => true;

    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        var list = new List<string>();

        // the context contains the property descriptor
        // the property descriptor has all custom attributes defined on the property
        // just get it (with proper null handling)
        var choices = context.PropertyDescriptor.Attributes.OfType<ListTypeConverterAttribute>().FirstOrDefault()?.List;
        if (choices != null)
        {
            list.AddRange(choices);
        }
        return new StandardValuesCollection(list);
    }
}