Dynamically set readonly attribute of properties in a PropertyGrid

Michael Mankus picture Michael Mankus · Oct 28, 2013 · Viewed 12.9k times · Source

I have a PropertyGrid that I used to display the properties in a helper class. I assign the helper class to the PropertyGrid like this:

myPropertyGrid.SelectedObject = mySettingsHelper;

In the helper class I assign the ReadOnlyAttribute at design time like this:

[DisplayName("DisplayExA"),
Description("DescriptionExA"),
ReadOnlyAttribute(true)]
public string PropertyA { get; set; }

[DisplayName("DisplayExB"),
Description("DescriptionExB"),
ReadOnlyAttribute(false)]
public string PropertyB { get; set; }

[DisplayName("DisplayExC"),
Description("DescriptionExC"),
ReadOnlyAttribute(true)]
public string PropertyC { get; set; }

But now I need to be able to change this attribute on individual properties dynamically during runtime. Based on certain criteria some of these properties may need to be read-only or not read-only. How would I make the change dynamically at runtime?

EDIT:

I tried the following code but this sets the ReadOnly attribute for every instance of the object! I want to do it per object. Sometimes one object might have PropertyA read-only while a second object has PropertyA to not be read-only.

public static class PropertyReadOnlyHelper
{
    public static  void SetReadOnly(object container, string name, bool value)
    {
        try
        {
            PropertyDescriptor descriptor = TypeDescriptor.GetProperties(container.GetType())[name];
            ReadOnlyAttribute attribute = (ReadOnlyAttribute)descriptor.Attributes[typeof(ReadOnlyAttribute)];
            FieldInfo fieldToChange = attribute.GetType().GetField("isReadOnly",
                                                System.Reflection.BindingFlags.NonPublic |
                                                System.Reflection.BindingFlags.Instance);
            fieldToChange.SetValue(attribute, value);
        }
        catch { }
    }
}

Answer

Michael Mankus picture Michael Mankus · Oct 29, 2013

I was able to do exactly what I need (object level assignment of the read-only attribute) using the library from this CodeProject article. What is nice is that it enables me to still use the .NET PropertyGrid and just use the custom attributes to handle the dynamic settings.