Question

I made the following custom PropertyDescriptor

public class CustomProperty : PropertyDescriptor
{
    private PropertyDescriptor _innerPropertyDescriptor;
    private bool _ronly;

    public CustomProperty(PropertyDescriptor inner, Attribute[] attrs)
        : base(inner.Name, attrs)
    {
        _innerPropertyDescriptor = inner;
        _ronly = inner.IsReadOnly;           
    }
    public override object GetValue(object component)
    {
        return _innerPropertyDescriptor.GetValue(component);
    }
    public override bool SupportsChangeEvents
    {
        get { return true; }
    }

    public override Type PropertyType
    {
        get { return _innerPropertyDescriptor.GetType(); }
    }

    public override void ResetValue(object component)
    {
        // Not relevant.
    }

    public override void SetValue(object component, object value)
    {
        _innerPropertyDescriptor = (CustomProperty)value;
    }

    public override bool ShouldSerializeValue(object component)
    {
        return false;
    }

    public override bool CanResetValue(object component)
    {
        return true;
    }

    public override Type ComponentType
    {
        get { return _innerPropertyDescriptor.GetType(); }
    }
    public override bool IsReadOnly
    {
        get
        {
            return false;
        }
    }
}

This PropertyDescriptor will be used for the following class

public class MyClass : ICustomTypeDescriptor
{
    #region MyClass Properties
    ......
    #endregion
    #region ICustomTypeDescriptor Implementation
    public AttributeCollection GetAttributes()
    {
        return TypeDescriptor.GetAttributes(this,true);
    }
    public string GetClassName()
    {
        return TypeDescriptor.GetClassName(this, true);
    }
    public string GetComponentName()
    {
        return TypeDescriptor.GetComponentName(this, true);
    }
    public TypeConverter GetConverter()
    {
        return TypeDescriptor.GetConverter(this, true);
    }
    public EventDescriptor GetDefaultEvent()
    {
        return TypeDescriptor.GetDefaultEvent(this, true);
    }
    public PropertyDescriptor GetDefaultProperty()
    {
        return TypeDescriptor.GetDefaultProperty(this, true);
    }
    public object GetEditor(System.Type editorBaseType)
    {
        return TypeDescriptor.GetEditor(this,editorBaseType, true);
    }
    public EventDescriptorCollection GetEvents(System.Attribute[] attributes)
    {
        return TypeDescriptor.GetEvents(this,attributes, true);
    }
    public EventDescriptorCollection GetEvents()
    {
        return TypeDescriptor.GetEvents(this, true);
    }
    public PropertyDescriptorCollection GetProperties(System.Attribute[] attributes)
    {
        PropertyDescriptorCollection originalCollection = TypeDescriptor.GetProperties(this,attributes,true);
        PropertyDescriptor[] pds = new PropertyDescriptor[originalCollection.Count];
        originalCollection.CopyTo(pds,0);
        PropertyDescriptorCollection newCollection = new PropertyDescriptorCollection(pds);
        for (int i = 0; i < originalCollection.Count; i++)
        {
            PropertyDescriptor pd = originalCollection[i];
            List<Attribute> la = new List<Attribute>();
            foreach (Attribute attribute in pd.Attributes)
                la.Add(attribute);
            CustomProperty cp = new CustomProperty(pd, la.ToArray());                
            newCollection.RemoveAt(i);
            newCollection.Insert(i, cp);
        }         
        return newCollection;
    }
    public PropertyDescriptorCollection GetProperties()
    {
        return TypeDescriptor.GetProperties(this, true);
    }
    public object GetPropertyOwner(PropertyDescriptor pd)
    {
        return this;
    }
    #endregion
}

What i did in this implementation, is to rewrite the MyClass properties to have the possibility to manage the Reset functionality from the Visual Studio PropertyGrid. Everything seems working good, but this implementation causes a wrong effect: all my new properties stored in the PropertyDescriptorCollection are all ReadOnly!! I can't understand why!? I tried everything, i put also a return false; in the IsReadOnly property of CustomProperty but no way. The properties appears always ReadOnly in the PropertGrid.

Anyone have an idea?

Was it helpful?

Solution

Your PropertyType and ComponentType implementations are broken. They sould return the inner property's PropertyType / ComponentType. By returning GetType you are returning something like ReflectionPropertyDescriptor, which is neither editable nor convertible.

    public override Type PropertyType
    {
        get { return _innerPropertyDescriptor.PropertyType; }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top