2011-12-20 3 views
1

У меня есть класс, созданный для использования с элементом управления PropertyGrid в приложении VB.Net. Одним из свойств класса:Как изменить атрибут TypeConverter свойства во время выполнения?

Private _someProp As String 

    <Browsable(True), _ 
    BindableAttribute(False), _ 
    DesignOnly(False), _ 
    DescriptionAttribute("Some Property Description"), _ 
    TypeConverter(GetType(propList1)), _ 
    DisplayName("Some Property")> _ 
    Public Property someProp() As String 
     Get 
      Return _someProp 
     End Get 
     Set(ByVal Value As String) 
      _someProp = Value     
     End Set 
    End Property 

Я хочу изменить атрибут TypeConverter этого свойства во время выполнения. Я в настоящее время изменения других атрибутов, как это (например только для чтения, Browsable.):

Dim descriptor As PropertyDescriptor = TypeDescriptor.GetProperties(Me.GetType)("someProp") 
Dim attrib_r As ReadOnlyAttribute = descriptor.Attributes(GetType(ReadOnlyAttribute)) 
Dim isReadOnly As System.Reflection.FieldInfo = attrib_r.GetType.GetField("isReadOnly", Reflection.BindingFlags.NonPublic + Reflection.BindingFlags.Instance) 
isReadOnly.SetValue(attrib_r, True) 

Однако, я не в состоянии применить подобную технику, чтобы изменить атрибут TypeConverter. Переменная typeConv не «ничего», когда я пытаюсь это:

Dim descriptor As PropertyDescriptor = TypeDescriptor.GetProperties(Me.GetType)("someProp") 
Dim attrib As TypeConverterAttribute = descriptor.Attributes(GetType(TypeConverterAttribute)) 
Dim typeConv As System.Reflection.FieldInfo = attrib.GetType.GetField("typeConverter", Reflection.BindingFlags.NonPublic + Reflection.BindingFlags.Instance) 
typeConv.SetValue(attrib, IIf(someCondition, GetType(propList1), GetType(propList2))) 

ETA: TypeConverter в данном случае используется для отображения выпадающего меню в PropertyGrid, так что пользователи могут выбрать подходящее значение, вместо того, чтобы вводить в один. Я хочу изменить этот список во время выполнения.

ETA2: С помощью щедрой помощи вкладчика (который решил удалить ответ по какой-то причине) моя текущая позиция заключается в том, что я получаю поле в переменной typeConv, но я не могу его изменить. Я получаю сообщение об ошибке «Объект типа« System.RuntimeType »не может быть преобразован в тип« System.String »в инструкции typeConv.SetValue независимо от значения, которое я предоставляю - GetType (propeList2)/GetType (propeList2) .AssemblyQualifiedName/a случайная строка

Dim typeConv As System.Reflection.FieldInfo = attrib.GetType.GetField("typeName", BindingFlags.Instance Or _ 
                 BindingFlags.Public Or _ 
                 BindingFlags.NonPublic Or _ 
                 BindingFlags.FlattenHierarchy) 
typeConv.SetValue(attrib, value) 
+0

Возможно, вы ищете метод [Convert.ChangeType] (http://msdn.microsoft.com/en-us/library/dtb69x08.aspx), но, возможно, я просто неправильно понял ваше требование. –

+0

Спасибо @TimSchmelter. Я думаю, что это последнее. В этом случае TypeConverter используется для отображения выпадающего списка PropertyGrid, так что пользователи могут выбрать подходящее значение, вместо того, чтобы вводить один. Я хочу изменить этот список во время выполнения. – Apeksha

ответ

0

единственный способ, которым вы могли бы изменить ConverterTypeName во время выполнения, чтобы попытаться использовать отражение для доступа к частной струне члена typeName и установить это в AssemblyQualifiedName в Type.

Это то, что делает конструктор TypeConverterAttribute внутри.

+0

Спасибо! Я попробовал 'typeConv.SetValue (атрибут, GetType (propeList2) .AssemblyQualifiedName)', где typeConv - это поле typeName. Но это вызывает ошибку. Должен ли я делать это по-другому? – Apeksha

+0

Да: вам нужно попытаться получить имя самого типа из типа typeConv (оно личное, поэтому вам придется играть с BindingFlags), вызов SetValue в объекте-члене typeName. –

+0

Прошу прощения, я не понимаю. (Как указано во втором редактировании моего вопроса), я получил поле 'typeName' в' typeConv', используя 'Dim typeConv As System.Reflection.FieldInfo = attrib.GetType.GetField (" typeName ", BindingFlags.Instance или BindingFlags .Public или BindingFlags.NonPublic или BindingFlags.FlattenHierarchy). Я получаю сообщение об ошибке в инструкции SetValue. Я не уверен, что это правильный способ изменить значение поля typeName. – Apeksha

Смежные вопросы