solution de Marc applique brutalement le EditorAttribute au barreau de type dans le monde. Si vous avez une disposition délicate, vous pouvez plutôt annoter les propriétés d'une instance spécifique. Hélas, ce n'est pas possible avec TypeDescriptor.AddAttributes
Ma solution était d'écrire un wrapper ViewModel<T>
, qui copie les propriétés de T, en annotant certaines avec des attributs supplémentaires. Supposons que nous ayons une datum
variable de rapport de type, nous utiliserions comme ça
var pretty = ViewModel<Report>.DressUp(datum);
pretty.PropertyAttributeReplacements[typeof(Smiley)] = new List<Attribute>() { new EditorAttribute(typeof(SmileyEditor),typeof(UITypeEditor))};
propertyGrid1.SelectedObject = pretty;
Où ViewModel<T>
est défini:
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);
}
}
Tel que défini ci-dessus, ce substitue les propriétés d'un type particulier, mais vous peut substituer des propriétés par nom si vous avez besoin de la plus grande résolution.
Marc, bien joué. Je vous aurais conseillé de créer un descripteur de type personnalisé et le fournisseur pour le publier, mais votre méthode est un bon raccourci pour enregistrer le fournisseur derrière la scène et injecter l'éditeur !! J'ai appris quelque chose. –
Wow, c'est très simple en pratique. Merci! –
C'est parfait! Je travaille sur une bibliothèque de dessin et je voulais fournir le support de l'éditeur PropertyGrid pour les objets sans prendre une dépendance sur Windows Forms de la bibliothèque d'objets afin de décorer les propriétés. Cette solution me permet de créer les éditeurs en dehors de la bibliothèque principale et de les ajouter lors de l'exécution. –