views:

213

answers:

3

Sigh, another PropertyGrid question. I thought I could get around this until I ran into a problem where I couldn't actually avoid it.

I have a boolean property that sometimes needs to be read-only and sometimes needs to be changeable depending on the object selected from a TreeView.

My question is how can I change the ReadOnlyAttribute of a property dynamically? Obviously, creating a boolean variable and then trying to set it like ReadOnlyAttribute(boolVar) doesn't work and now I'm out of ideas.

The only solution I can think of is creating separate, near-identical classes for items where this property is writable and one for read-only, but this seems a bit unelegant to me.

Help? :)

+1  A: 

What I would do is create a base class with a protected version the property, then create two classes that inherit the base class that have the readonly and the non-readonly bits.

Tom Anderson
+3  A: 

You can provide dynamic information about the properties of a class to a property grid by implementing ICustomTypeDescriptor.

The property grid will call ICustomTypeDescriptor.GetProperties() and you return a collection of objects derived from PropertyDescriptors. In your implementation you can override the PropertyDescriptor.IsReadOnly property and implement your logic.

This is quite a bit of work in the first place, but it gives you the possibility to dynamically return a property name and description (helpful for localization), dynamically mark properties as read-only, dynamiclly show and hide properties, and do a lot of other usefull things.

Daniel Brückner
A: 

You could try something along these lines to avoid the type conversion involved with multiple classes:

class TestClass
{
    private bool isMyPropertyReadOnly;

    public bool IsMyPropertyReadOnly
    {
        get { return isMyPropertyReadOnly; }
        set { isMyPropertyReadOnly = value; }
    }

    private int myVar;

    public int MyProperty
    {
        get { return myVar; }

        set
        {
            if (isMyPropertyReadOnly)
            {
                throw new System.Exception("The MyProperty property is read-only.");
            }
            else
            {
                myVar = value;
            }
        }
    }
}
Andy West