di Marc applica senza mezzi termini l'EditorAttribute al bar tipo a livello mondiale. Se si dispone di una disposizione delicata, è preferibile annotare le proprietà di istanze specifiche. Purtroppo, questo non è possibile con TypeDescriptor.AddAttributes
La mia soluzione era scrivere un wrapper ViewModel<T>
, che copia le proprietà da T, annotandone alcune con attributi aggiuntivi. Supponiamo di avere una variabile di tipo datum
relazione, saremmo usare in questo modo
var pretty = ViewModel<Report>.DressUp(datum);
pretty.PropertyAttributeReplacements[typeof(Smiley)] = new List<Attribute>() { new EditorAttribute(typeof(SmileyEditor),typeof(UITypeEditor))};
propertyGrid1.SelectedObject = pretty;
Dove ViewModel<T>
è definito:
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);
}
}
come sopra definito, questo sostituisce le proprietà di un tipo specifico, ma si può sostituire le proprietà per nome se è necessaria la risoluzione maggiore.
fonte
2012-09-25 16:06:51
Marc, ben fatto. Avrei consigliato di creare un descrittore di tipo personalizzato e il provider per pubblicarlo, ma il tuo metodo è una buona scorciatoia per registrare il provider dietro la scena e iniettare l'editor !! Imparato qualcosa –
Wow, è molto semplice nella pratica. Grazie! –
Questo è perfetto! Sto lavorando su una libreria di disegni e volevo fornire il supporto dell'editor PropertyGrid per gli oggetti senza prendere una dipendenza da Windows Form dalla libreria di oggetti per decorare le proprietà. Questa soluzione mi consente di creare gli editor all'esterno della libreria principale e aggiungerli in fase di runtime. –