jeudi 19 novembre 2015

Unable to create Generic CustomAttributeData properly when using programatically generated Enum

I am trying to source a PropertyGrid with a dynamically generated object.

For combo selections on this property grid, I have built a TypeConverter (where T is an enum, defining the list of options):

    public class TypedConverter<T> : StringConverter where T : struct, IConvertible
    {
        ...

        public override System.ComponentModel.TypeConverter.StandardValuesCollection
            GetStandardValues(ITypeDescriptorContext context)
        {
            if (!typeof(T).IsEnum) throw new ArgumentException("T must be an enumerated type");            

            string[] values = Enum.GetValues(typeof(T)).OfType<object>().Select(o => o.ToString()).ToArray();

            return new StandardValuesCollection(values);
        }

    }

I can then add a custom attribute to the property, referencing this TypeConverter, as below (typedConverterGenericType is the the type of TypedConverter with an enum generic argument)

CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(typeof(TypeConverterAttribute).GetConstructor(new Type[] { typeof(Type) }), new Type[] { typedConverterGenericType });

propertyBuilder.SetCustomAttribute(attributeBuilder);

This works great, as long as the Enum in question is hardcoded: AddTypeConverterAttribute(propertyBuilder, typeof(TypedConverter<Fred>));. In the debugger, the attribute on the property gives me {[System.ComponentModel.TypeConverterAttribute( ....

However, when I use a dynamically built enum (that I have determined is generated properly in reflection) does not work:

   Type enumType = enumBuilder.CreateType();//This generates a proper enum, as I have determined in reflection

   Type converterType = typeof(TypedConverter<>);

   Type typedConverterType = converterType.MakeGenericType(enumType);

   AddTypeConverterAttribute(propertyBuilder, typedConverterType);

In the debugger, the attribute on the property now gives me {System.Reflection.CustomAttributeData}, and drilling into this, I have an error on the ConstructorArguments ... Mscorlib_CollectionDebugView<System.Reflection.CustomAttributeData>(type.GetProperties()[1].CustomAttributes).Items[4].ConstructorArguments' threw an exception of type 'System.IO.FileNotFoundException'

What am I doing wrong? How can I get the TypeConverter attribute set properly?

EDIT: In case someone wants to see how I add the attribute

private void AddTypeConverterAttribute(PropertyBuilder propertyBuilder, Type typedConverterGenericType)
{
   CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(typeof(TypeConverterAttribute).GetConstructor(new Type[] { typeof(Type) }), new Type[] { typedConverterGenericType });

   propertyBuilder.SetCustomAttribute(attributeBuilder);        
}





Aucun commentaire:

Enregistrer un commentaire