4

У меня есть класс, который реализует ICustomTypeDescriptor, и просматриваться и редактироваться пользователем в PropertyGrid. Мой класс также имеет свойство IsReadOnly, которое определяет, сможет ли пользователь впоследствии сохранить свои изменения. Я не хочу позволять пользователю вносить изменения, если они не смогут сэкономить. Поэтому, если IsReadOnly истинно, я хочу переопределить любые свойства, которые в противном случае были бы доступны для редактирования только для чтения в сетке свойств.свойства изменяются динамически возвращаемые ICustomTypeDescriptor.GetProperties к READONLY

Я пытаюсь использовать метод GetProperties из ICustomTypeDescriptor добавить ReadOnlyAttribute каждому PropertyDescriptor. Но, похоже, это не работает. Вот мой код.

public PropertyDescriptorCollection GetProperties(Attribute[] attributes) 
{ 
    List<PropertyDescriptor> fullList = new List<PropertyDescriptor>(); 

    //gets the base properties (omits custom properties) 
    PropertyDescriptorCollection defaultProperties = TypeDescriptor.GetProperties(this, attributes, true); 

    foreach (PropertyDescriptor prop in defaultProperties) 
    { 
     if(!prop.IsReadOnly) 
     { 
      //adds a readonly attribute 
      Attribute[] readOnlyArray = new Attribute[1]; 
      readOnlyArray[0] = new ReadOnlyAttribute(true); 
      TypeDescriptor.AddAttributes(prop,readOnlyArray); 
     } 

     fullList.Add(prop); 
    } 

    return new PropertyDescriptorCollection(fullList.ToArray()); 
} 

Это даже правильный способ использования TypeDescriptor.AddAttributes()? При отладке после вызова атрибут AddAttributes() по-прежнему имеет одинаковое количество атрибутов, ни один из которых не является атрибутом ReadOnlyAttribute.

ответ

2

TypeDescriptor.AddAttributes добавляет уровня класса атрибутов данного объекта или типа объекта, а не свойства уровня атрибутов. Кроме того, я не думаю, что это имеет какой-то эффект, кроме как в поведении возвращаемого TypeDescriptionProvider.

Вместо этого я бы завернуть все дескрипторы свойств по умолчанию, как это:

public PropertyDescriptorCollection GetProperties(Attribute[] attributes) 
{ 
    return new PropertyDescriptorCollection(
     TypeDescriptor.GetProperties(this, attributes, true) 
      .Select(x => new ReadOnlyWrapper(x)) 
      .ToArray()); 
} 

где ReadOnlyWrapper является классом, как это:

public class ReadOnlyWrapper : PropertyDescriptor 
{ 
    private readonly PropertyDescriptor innerPropertyDescriptor; 

    public ReadOnlyWrapper(PropertyDescriptor inner) 
    { 
     this.innerPropertyDescriptor = inner; 
    } 

    public override bool IsReadOnly 
    { 
     get 
     { 
      return true; 
     } 
    } 

    // override all other abstract members here to pass through to the 
    // inner object, I only show it for one method here: 

    public override object GetValue(object component) 
    { 
     return this.innerPropertyDescriptor.GetValue(component); 
    } 
}