2012-04-29 6 views
1

Я использую PropertyGrid в своем приложении. Мне нужно было изменить видимость и readonly для некоторых свойств во время выполнения на пользовательских данных критериев.Ищет событие, которое срабатывает при вызове свойства

Хотя я не нашел что-то легко & готов к этому, я нашел обходной путь, изменив ReadOnlyAttribute и BrowsableAttribute свойства во время выполнения, как:

protected void SetBrowsable(string propertyName, bool value) 
{ 
    PropertyDescriptor property = TypeDescriptor.GetProperties(GetType())[propertyName]; 
    BrowsableAttribute att = (BrowsableAttribute)property.Attributes[typeof(BrowsableAttribute)]; 
    FieldInfo cat = att.GetType().GetField("browsable", BindingFlags.NonPublic | BindingFlags.Instance); 

    if (property.Attributes.Cast<Attribute>().Any(p => p.GetType() == typeof(BrowsableAttribute))) 
     cat.SetValue(att, value); 
} 

protected void SetReadOnly(string propertyName, bool value) 
{ 
    PropertyDescriptor property = TypeDescriptor.GetProperties(GetType())[propertyName]; 
    ReadOnlyAttribute att = (ReadOnlyAttribute)property.Attributes[typeof(ReadOnlyAttribute)]; 
    FieldInfo cat = att.GetType().GetField("isReadOnly", BindingFlags.NonPublic | BindingFlags.Instance); 

    if (property.Attributes.Cast<Attribute>().Any(p => p.GetType() == typeof(ReadOnlyAttribute))) 
     cat.SetValue(att, value); 
} 

Теперь моя проблема в том, что там, где я должен вызывать эти методы? есть ли какое-либо событие, которое я могу обработать для object, чтобы вызвать эти методы? Возможно, реализовав интерфейс.

ответ

1

Нет встроенного события, которое срабатывает при вызове свойства-get, если только вы его не написали.

Конечно, если вы создаете пользовательский дескриптор (PropertyDescriptor, как правило, прикован к дескриптору отражения в качестве декоратора) можно перехватить доступ с помощью дескриптора только (связывание данных и т.д.), и делать все, что вы хотите, - но для произвольных типов (включая те, которые вы не писали).

Установка значений атрибутов через отражение во время выполнения ... не велика. Это в основном связано с кэшированием TypeDescriptor. Если вы это сделаете, предпочтительнее использовать TypeDescriptor.AddAttributes (или аналогичный). Однако то, что вы пытаетесь сделать, сделано гораздо более правильно, реализуя пользовательскую модель. В зависимости от того, где вы показываете это, это может быть сделано с помощью одного или:

  • добавления пользовательских TypeConverter, перекрывая GetProperties, и предоставлять пользовательские дескрипторы во время выполнения на основе данных - работает в первую очередь для PropertyGrid
  • реализации ICustomTypeDescriptor в вашем объекте, внедряя GetProperties и предоставляя пользовательские дескрипторы во время выполнения на основе данных - работает для большинства элементов управления
  • , добавляя настраиваемый TypeDescriptionProvider и связывая его с типом (TypeDescriptor.AddProvider), предоставляя ICustomTypeDescriptor, который ведет себя, как указано выше; это отделяет объект от дескриптора voodoo

Al из этих сложны! Самый простой вариант - вариант TypeConverter, который хорошо работает, потому что вы указываете PropertGrid. Наследовать от ExpandableObjectConverter и переопределять GetProperties, при необходимости фильтровать и поставлять собственный дескриптор для чтения только по мере необходимости. Затем прикрепите TypeConverterAttribute к вашему типу, указав свой собственный тип конвертера.

Акцент: эта ветка .NET довольно сложна, неясна и уменьшает использование. Но это работает.

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