PropertyGrid property for readonly at the object level

I want to display multiple instances of the same class in my PropertyGrid . The class is as follows:

 public class Parameter { [Description("the name")] public string Name { get; set; } [Description("the value"), ReadOnly(true)] public string Value { get; set; } [Description("the description")] public string Description { get; set; } } 

I have many instances of this class in a TreeView . When I select one of them in my TreeView , the properties are displayed in the PropertyGrid , as expected. So far so good, but I want to configure this behavior as follows:

For each individual instance, I want the user to not be able to modify a specific property. By setting ReadOnly(true) to my class (as you can see in the example above), all Value properties will be disabled at the class level.

After some research, I found the following solution that gives me the ability to enable / disable a specific property at runtime:

 PropertyDescriptor descriptor = TypeDescriptor.GetProperties(this)["Value"]; ReadOnlyAttribute attr = (ReadOnlyAttribute)descriptor.Attributes[typeof(ReadOnlyAttribute)]; FieldInfo isReadOnly = attr.GetType().GetField( "isReadOnly", BindingFlags.NonPublic | BindingFlags.Instance); isReadOnly.SetValue(attr, false); 

This approach works fine, but unfortunately at the class level. This means that if I set Value isReadOnly to false , all my Parameter objects have a Value property that can be written. But I want this ONLY on one specific object (thus, at the object level). I really don't want to create separate classes for the read / write and readonly properties.

As I run out of ideas, your help is much appreciated :)

Thanks in advance!

EDIT: I need readonly properties to be unavailable, so the user can see that he is not allowed or cannot edit them.

+7
source share
2 answers

EDIT . The related article has been deleted (I hope it’s just temporary). You can evaluate a viable alternative in answers to How to add a property level attribute to a TypeDescriptor at runtime? . Basically you have to add (at run time) ReadOnlyAttribute via TypeDescriptor for this property.

<h / "> Take a look at this old but nice article about CodeProject , it contains many useful tools for PropertyGrid .

Basically you provide a class or delegate that will be used to get attributes of your properties. Since it will cause the instance of the object for which you want to get attributes to be transferred, then you can return (or not) ReadOnlyAttribute taking into account each object. In short: apply PropertyAttributesProviderAttribute to the property, write your own provider and replace the attributes from the PropertyAttributes collection based on the object itself (not the class)

+4
source

You can wrap the object with a custom type descriptor, but I think that would be redundant, because you need to create a new class derived from typedescriptor.

So, the simplest solution would be to have a flag, something like:

 public class Parameter { private string thevalue; [Browsable(false)] public bool CanEditValue { get; set; } [Description("the name")] public string Name { get; set; } [Description("the description")] public string Description { get; set; } [Description("the value"), ReadOnly(true)] public string Value { get { return this.thevalue; } set { if (this.CanEditValue) this.thevalue = value; } } } 
+1
source

All Articles