de Marc rodeos aplica la EditorAttribute a la barra de tipo a nivel mundial. Si tiene una disposición delicada, puede anotar las propiedades de instancias específicas. Por desgracia, eso no es posible con TypeDescriptor.AddAttributes
Mi solución fue escribir un contenedor ViewModel<T>
, que copia las propiedades de T, anotando algunas con atributos adicionales. Supongamos que tenemos una variable datum
del tipo de informe, nos gustaría utilizar de esta manera
var pretty = ViewModel<Report>.DressUp(datum);
pretty.PropertyAttributeReplacements[typeof(Smiley)] = new List<Attribute>() { new EditorAttribute(typeof(SmileyEditor),typeof(UITypeEditor))};
propertyGrid1.SelectedObject = pretty;
Dónde ViewModel<T>
se define:
public class ViewModel<T> : CustomTypeDescriptor
{
private T _instance;
private ICustomTypeDescriptor _originalDescriptor;
public ViewModel(T instance, ICustomTypeDescriptor originalDescriptor) : base(originalDescriptor)
{
_instance = instance;
_originalDescriptor = originalDescriptor;
PropertyAttributeReplacements = new Dictionary<Type,IList<Attribute>>();
}
public static ViewModel<T> DressUp(T instance)
{
return new ViewModel<T>(instance, TypeDescriptor.GetProvider(instance).GetTypeDescriptor(instance));
}
/// <summary>
/// Most useful for changing EditorAttribute and TypeConvertorAttribute
/// </summary>
public IDictionary<Type,IList<Attribute>> PropertyAttributeReplacements {get; set; }
public override PropertyDescriptorCollection GetProperties (Attribute[] attributes)
{
var properties = base.GetProperties(attributes).Cast<PropertyDescriptor>();
var bettered = properties.Select(pd =>
{
if (PropertyAttributeReplacements.ContainsKey(pd.PropertyType))
{
return TypeDescriptor.CreateProperty(typeof(T), pd, PropertyAttributeReplacements[pd.PropertyType].ToArray());
}
else
{
return pd;
}
});
return new PropertyDescriptorCollection(bettered.ToArray());
}
public override PropertyDescriptorCollection GetProperties()
{
return GetProperties(null);
}
}
Como se definió anteriormente, este sustituye propiedades de un tipo específico, pero puede sustituir propiedades por nombre si necesita la mayor resolución.
Marc, bien hecho. Hubiera recomendado crear un descriptor de tipo personalizado y el proveedor para publicarlo, pero su método es un buen atajo para registrar el proveedor detrás de la escena e inyectar el editor. Aprendí algo. –
Guau, eso es muy simple en la práctica. ¡Gracias! –
¡Esto es perfecto! Estoy trabajando en una biblioteca de dibujo y quería proporcionar compatibilidad con el editor de PropertyGrid para objetos sin tomar una dependencia de Windows Forms de la biblioteca de objetos para decorar las propiedades. Esta solución me permite crear editores fuera de la biblioteca principal y agregarlos en tiempo de ejecución. –