Я пытаюсь создать PropertyGrid с динамически созданным объектом.Невозможно правильно создать Generic CustomAttributeData при использовании программно сгенерированного Enum
Для комбинированных выборов на этой собственности сетки, я построил TypeConverter (где T является перечисление, определяющий список опций):
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);
}
}
Затем я могу добавить пользовательский атрибут к свойству, ссылки это TypeConverter, как показано ниже (typedConverterGenericType является типом TypedConverter с перечислениями родового аргументом)
CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(typeof(TypeConverterAttribute).GetConstructor(new Type[] { typeof(Type) }), new Type[] { typedConverterGenericType });
propertyBuilder.SetCustomAttribute(attributeBuilder);
Это работает большого, до тех пор, как Enum в вопросе зашито: AddTypeConverterAttribute(propertyBuilder, typeof(TypedConverter<Fred>));
. В отладчике атрибут свойства дает мне {[System.ComponentModel.TypeConverterAttribute(...
.
Однако, когда я использую динамически построенный перечисление (что я определил правильно генерироваться в отражении) не работает:
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);
В отладчике, атрибут на имущество теперь дает мне {System.Reflection.CustomAttributeData}
, и сверление в этом, у меня есть ошибка на ConstructorArguments ... Mscorlib_CollectionDebugView<System.Reflection.CustomAttributeData>(type.GetProperties()[1].CustomAttributes).Items[4].ConstructorArguments' threw an exception of type 'System.IO.FileNotFoundException'
Что я делаю неправильно? Как я могу правильно установить атрибут TypeConverter?
EDIT: В случае, если кто-то хочет посмотреть, как добавить атрибут
private void AddTypeConverterAttribute(PropertyBuilder propertyBuilder, Type typedConverterGenericType)
{
CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(typeof(TypeConverterAttribute).GetConstructor(new Type[] { typeof(Type) }), new Type[] { typedConverterGenericType });
propertyBuilder.SetCustomAttribute(attributeBuilder);
}
EDIT2
тестирование подтверждает это проблема с динамически построенного перечисления - если я создаю общий тип с Type typedConverterType = converterType.MakeGenericType(typeof(Fred));
он отлично работает.
EDIT 3
Мой тестовый проект доступен here. Он читает некоторые JSON из Resouces и пытается сгенерировать класс, тип которого описан этим JSON.
Я создаю экземпляр этого класса (Activator.CreateInstance
), который будет источником PropertyGrid. Чтобы получить комбо-выбор в этом PropertyGrid, я создаю Type с атрибутом TypedConverter, где T представляет собой перечисление, которое описывает значения в комбинированном выборе.
Это прекрасно работает для закодированных перечислений, но не для тех, сгенерированных программно
Вы пробовали 'общественного EnumBuilder DefineEnum (имя строки , Видимость TypeAttributes, Тип baseType); 'в' System.Reflection.Emit.ModuleBuilder'? Вот пример: https://msdn.microsoft.com/en-us/library/system.reflection.emit.enumbuilder(v=vs.110).aspx – mrtig
@mrtig Да, я не включил его для краткости ради. 'EnumBuilder builder = moduleBuilder.DefineEnum (name, TypeAttributes.Public, typeof (int));' как я получаю свой enumBuilder. – johnc