0

I have taken the code inside the set from codeproject. I'm trying to make the property Phone readonly, if the QRType is not equal to Contact or Phone (QRType is an enum):

public QRType Type 
{ 
    get { return type; } 
    set 
    { 
        type = value;
        PropertyDescriptor descriptor = TypeDescriptor.GetProperties(GetType())["Phone"];
        ReadOnlyAttribute attribute = (ReadOnlyAttribute)
            descriptor.Attributes[typeof(ReadOnlyAttribute)];
        FieldInfo fieldToChange = attribute.GetType().GetField("isReadOnly",
                                                 BindingFlags.NonPublic |
                                                 BindingFlags.Instance);

        bool v = (type != QRType.Contact && type != QRType.Phone);
        fieldToChange.SetValue(attribute, v );       
    }
}

The above code does not work correctly and the Phone field is always grayed out, while setting the values like:

fieldToChange.SetValue(attribute, true );
fieldToChange.SetValue(attribute, false );

both works correctly. What is wrong with it?

UPdate: It is funny that without using && it works:

fieldToChange.SetValue(attribute, type != QRType.Contact);
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
Ashkan Mobayen Khiabani
  • 33,575
  • 33
  • 102
  • 171
  • 1
    The fact that `ReadOnlyAttribute.IsReadOnly` is read-only should be a red flag not to attempt to modify it. If you were writing a component which makes use of `ReadOnlyAttribute`, I wrote some code based on your component, and I used the exact same code you put in the question here, would you support this in your component? I may be wrong, but I suspect you would not. –  Oct 13 '16 at 05:36
  • @hvd I'd be really glad to use it. Thanks a lot – Ashkan Mobayen Khiabani Oct 13 '16 at 05:41
  • If `ReadOnly` attribute was not sealed there was a chance to provide a custom implementation for that. But currently the main option which you have is using a custom type descriptor. Your object can implement `ICustomTypeDescriptor`, but it's better to implement a custom type descriptor separately and register it for your class. – Reza Aghaei Oct 13 '16 at 06:18
  • In my current implementation I've put the rule of making property readonly/writable in custom property descriptor class, but if you get the idea, you can decouple the property descriptor from the rule and inject the rule using some attributes. As an example of such idea, take a look at [this post](http://stackoverflow.com/questions/38503146/combining-control-attributes). – Reza Aghaei Oct 13 '16 at 06:20

0 Answers0