Aggiungi un attributo di categoria a un PropertyDescriptor
-
05-07-2019 - |
Domanda
Ho una serie di PropertyDescriptor personalizzati che voglio aggiungere anche categorie in modo che vengano visualizzati in modo più organizzato in un PropertyGrid. Voglio che ogni tipo di PropertyDescriptor vada in una categoria specifica.
Ho provato a usare TypeDescriptor.AddAttributes () per aggiungere attributi a un PropertyDescriptor esistente, ma l'attributo della categoria non è stato aggiunto.
CategoryAttribute intrinsicPropertyCategory = new CategoryAttribute("Intrinsic Properties");
currentDescriptor = new IntrinsicPropertyDescriptor(def);
TypeDescriptor.AddAttributes(currentDescriptor, new Attribute[] { intrinsicPropertyCategory });
Ho anche provato a usare TypeDescriptor.AddAttributes () nel costruttore per uno dei miei PropertyDescriptors come mostrato di seguito. Ma non funziona neanche.
public IntrinsicPropertyDescriptor(IntrinsicPropertyDef propDef): base(propDef.Key, propDef.Attributes)
{
this._type = propDef.Type;
this._key = propDef.Key;
this._readOnly = propDef.ReadOnly;
CategoryAttribute intrinsicPropertyCategory = new CategoryAttribute("Intrinsic Properties");
TypeDescriptor.AddAttributes(this, new Attribute[] { intrinsicPropertyCategory });
}
Preferirei non passare il tempo a entrare nei dettagli del perché sto facendo quello che sto facendo. Ma nell'esempio sopra IntrinsicPropertyDef è una classe che definisce una proprietà che include un nome, un nome visualizzato e un tipo. Quindi propDef.Attributes include DisplayNameAttribute.
Un IntrinsicPropertyDef può essere visualizzato con due diversi PropertyDescriptors personalizzati IntrinsicPropertyDescriptor e InferedIntrinsicPropertyDescriptor. Ogni IntrinsicPropertyDescriptor dovrebbe avere un attributo di categoria " Proprietà intrinseche " ;, e ogni InferedIntrinsicPropertyDescriptor dovrebbe avere un attributo di categoria " Proprietà intrinseche dedotte " ;.
Soluzione
Credo che puoi semplicemente sostituire la Categoria
:
public override string Category { get {return "Foo";}}
Per altri scenari; in generale con un PropertyDescriptor
personalizzato, si specificano gli attributi nel costruttore. Dovrai espandere l'argomento Attribute []
per includere CategoryAttribute
. Se è necessario eseguire qualsiasi elaborazione, è possibile utilizzare un metodo statico - non testato:
static Attribute[] AddCategory(Attribute[] attributes, string category) {
Array.Resize(ref attributes, attributes.Length + 1);
attributes[attributes.Length - 1] = new CategoryAttribute(category);
return attributes;
}
public IntrinsicPropertyDescriptor(IntrinsicPropertyDef propDef)
: base(propDef.Key, AddCategory(propDef.Attributes, "Foo"))
{...}
Inoltre, nota che per usare un PropertyDescriptor
, il sistema deve trovarlo ... le regole di risoluzione sono:
- per
PropertyGrid
, ilTypeConverter
fornisce le proprietà, impostando per impostazione predefinita le proprietà di un'istanza (sotto) - per un'istanza:
-
ICustomTypeDescriptor
è selezionato - altrimenti verifica la presenza di un
TypeDescriptionProvider
registrato per l'istanza o il tipo - altrimenti viene utilizzata la riflessione
-
- per un tipo:
- controlla un
TypeDescriptionProvider
registrato per il tipo - altrimenti viene utilizzata la riflessione
- controlla un
- per elenchi:
-
IListSource
viene controllato e risolto in un elenco (l'elaborazione continua) -
ITypedList
è selezionato - in caso contrario, il tipo di elenco viene verificato per un indicizzatore non oggetto, ovvero
pubblico SomeType this [int index] {get;}
- se tale viene trovato, vengono utilizzate le proprietà per il tipo
SomeType
, come definito sopra
- se tale viene trovato, vengono utilizzate le proprietà per il tipo
- altrimenti, se l'elenco non è vuoto, vengono utilizzate le proprietà della prima istanza (
list [0]
), come definito sopra - altrimenti, i metadati non sono disponibili
-