4

ICustomTypeDescriptor를 구현하는 클래스가 있으며 PropertyGrid에서 사용자가보고 편집합니다. 내 클래스에는 사용자가 나중에 변경 내용을 저장할 수 있는지 여부를 결정하는 IsReadOnly 속성도 있습니다. 저장하지 못하게되면 사용자가 변경하도록 허용하고 싶지 않습니다. IsReadOnly가 true 인 경우 속성 그리드에서 읽기 전용으로 편집 가능한 모든 속성을 재정의하려고합니다.ICustomTypeDescriptor.GetProperties에서 읽기 전용으로 반환하는 속성을 동적으로 변경합니다.

각 PropertyDescriptor에 ReadOnlyAttribute를 추가하기 위해 ICustomTypeDescriptor의 GetProperties 메서드를 사용하려고합니다. 그러나 그것은 작동하지 않는 것 같습니다. 여기 내 코드가있다.

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 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); 
    } 
}     
: ReadOnlyWrapper이 같은 클래스가

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