I want to display multiple instances of one class in my PropertyGrid
. The class looks like this:
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 that class in a TreeView
. When I select one of them in my TreeView
, the properties show up in the PropertyGrid
as expected. So far so good, but I want to customise this behaviour in the following way:
For each single instance I want to be able to prevent the user from modifying a specific property. By setting ReadOnly(true)
within my class (as you can see in the example above), all Value
properties will be disabled on a class-level.
After some research I found the following solution which gives me the opportunity 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 just fine but unfortunately also on class-level only. This means if I set the Value
's isReadOnly
to false
, all of my Parameter
-objects have the Value
property writeable. But I want this ONLY on that one particular object (thus object-level). I really don't want to create separate classes for read/write and readonly properties.
As I am running out of ideas, your help is much appreciated :)
Thanks in advance!
EDIT: I need the readonly properties to be grayed-out, so the user can see that it's not allowed or possible to edit them.
EDIT: Linked article has been removed (I hope just temporary). You can fine a viable alternative in answers to How to add property-level Attribute to the TypeDescriptor at runtime?. Basically you have to add (at run-time) ReadOnlyAttribute
through a TypeDescriptor
for that property.
PropertyGrid
.
Basically you provide a class or a delegate that will be used to get the attributes of your properties. Because it will be invoked passing the instance of the object you want to get attributes for then you'll be able to return (or not) the ReadOnlyAttribute
with a per object basis. Shortly: apply a PropertyAttributesProviderAttribute
to your property, write your own provider and replace attributes from the PropertyAttributes
collection based on the object itself (and not on the class)