views:

643

answers:

5

Hi, I have a class with a set of properties As given below.

class ContactInfo
{
    [ReadOnly(true)]
    [Category("Contact Info")]
    public string Mobile { get; set; }

    [Category("Contact Info")]
    public string Name{ get; set; }
}

The objects of this class is being assigned to a property grid, so that the users can update an existing contact. you can see that Mobile is marked as ReadOnly.

But, when I want to add an entirely new Contact, I would want the users to be able to edit the contact Mobile also. For that I need to remove the Readonly property dynamically from the Type, before assigning the object to the property grid. Is it possible?

+1  A: 

it's not possible at the moment to remove attributes dinamycally (at runtime)

as a suggestion you can do 2 classes: one with the attributes and one without

Omu
There's no need to make 2 classes, reflection can be used to modify the boolean field of the ReadOnly attribute and change it to false (not read only).
legenden
hmm, good call, I didn't thought about that :)
Omu
+1  A: 

I have to agree w/ Omu; you're really talking about two classes (view models) in this case, to support your two different views. Something like

CreateContactViewModel and EditContactViewModel

Paul
+4  A: 

You can not remove the attribute at runtime, but you can use reflection to change the ReadOnly attribute's ReadOnly private backing field to False. Making it the equivalent of [ReadOnly(false)]

See this article for details:

http://blog.codinglight.com/2008/10/changing-attribute-parameters-at.html

legenden
This is exactly what I wanted in my case.
SysAdmin
A: 

I followed up the suggestion by Legenden. Here is what I came up with

class ContactInfo
{
        [ReadOnly(true)]
        [Category("Contact Info")]
        public string Mobile { get; set; }

        [Category("Contact Info")]
        public string Name{ get; set; }

        public void SetMobileEdit(bool allowEdit)
        {
             PropertyDescriptor descriptor =  TypeDescriptor.GetProperties(this.GetType())["Mobile"];

             ReadOnlyAttribute attrib = (ReadOnlyAttribute)descriptor.Attributes[typeof(ReadOnlyAttribute)];

             FieldInfo isReadOnly = attrib.GetType().GetField("isReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);

             isReadOnly.SetValue(attrib, !allowEdit);
        }
}
SysAdmin
I think that while this works, it's not a good design. The responsibilities are bleeding.
Paul