Quiero mostrar varias instancias de una clase en mi PropertyGrid
. La clase tiene este aspecto:Propiedad de solo lectura PropertyGrid en el nivel de objeto
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; }
}
Tengo muchas instancias de esa clase en un TreeView
. Cuando selecciono uno de ellos en mi TreeView
, las propiedades aparecen en el PropertyGrid
como se esperaba. Hasta ahora todo bien, pero quiero personalizar este comportamiento de la siguiente manera:
Para cada instancia individual, deseo poder evitar que el usuario modifique una propiedad específica. Configurando ReadOnly(true)
dentro de mi clase (como puede ver en el ejemplo anterior), todas las propiedades de Value
se desactivarán en un de nivel de clase.
Después de algunas investigaciones he encontrado la solución después de lo que me da la oportunidad de activar/desactivar una propiedad específica en tiempo de ejecución:
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);
Este enfoque funciona muy bien, pero por desgracia también en un solo nivel de clase. Esto significa que si configuro Value
's isReadOnly
en false
, todos de mis Parameter
-objetos tienen la propiedad Value
escribible. Pero quiero SOLO esto en ese objeto en particular (por lo tanto, nivel de objeto). Realmente no quiero crear clases separadas para las propiedades de lectura/escritura y de solo lectura.
Como estoy quedando sin ideas, su ayuda es muy apreciada :)
Gracias de antemano!
EDITAR: Necesito que las propiedades de solo lectura estén atenuadas, por lo que el usuario puede ver que no está permitido o posible editarlas.
He leído todo el documento pero todavía no entiendo su idea. ¿Podría proporcionarme un pequeño ejemplo de código para hacerlo un poco más claro? Gracias por su tiempo :) –
Vea el párrafo * Uso dinámico * en ese artículo. En breve: aplique un atributo PropertyAttributesProviderAttribute a su propiedad, escriba su propio proveedor y reemplace los atributos de la colección PropertyAttributes en función del objeto mismo (y no de la clase). –
Como puedo ver en el código fuente, ¿esto requiere usar la implementación personalizada PropertyGrid de los autores para que funcione? En mi caso, tengo que usar un PropertyGrid existente que está dentro de una DLL (que no puedo modificar). –