Adicionar um atributo de categoria para um PropertyDescriptor
-
05-07-2019 - |
Pergunta
Eu tenho um conjunto de PropertyDescriptor personalizado que eu quero adicionar categorias também, então eles exibem de uma forma mais organizada em um PropertyGrid. Eu quero que cada tipo de PropertyDescriptor para entrar em uma categoria específica.
Eu tentei usar TypeDescriptor.AddAttributes () para adicionar atributos a um PropertyDescriptor existente, mas o atributo da categoria não é adicionada.
CategoryAttribute intrinsicPropertyCategory = new CategoryAttribute("Intrinsic Properties");
currentDescriptor = new IntrinsicPropertyDescriptor(def);
TypeDescriptor.AddAttributes(currentDescriptor, new Attribute[] { intrinsicPropertyCategory });
Eu também tentei usar TypeDescriptor.AddAttributes () no construtor para um dos meus PropertyDescriptors como mostrado abaixo. Mas isso não quer trabalhar.
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 });
}
Eu prefiro não gastar o tempo de ir para detalhes de por que eu estou fazendo o que estou fazendo. Mas no exemplo acima IntrinsicPropertyDef é uma classe que define uma propriedade, incluindo um nome, nome de exibição e Tipo. Então propDef.Attributes inclui o DisplayNameAttribute.
Um IntrinsicPropertyDef pode ser exibido com dois PropertyDescriptors personalizados diferentes IntrinsicPropertyDescriptor e InferedIntrinsicPropertyDescriptor. Cada IntrinsicPropertyDescriptor deve ter um atributo da categoria "intrínsecos Propriedades", e cada InferedIntrinsicPropertyDescriptor deve ter um atributo da categoria "Inferidos propriedades intrínsecas".
Solução
I acreditam você pode simplesmente substituir o Category
:
public override string Category { get {return "Foo";}}
Para outros cenários; em geral, com um PropertyDescriptor
personalizado, você especificar atributos no construtor. Você vai precisar para expandir o argumento Attribute[]
para incluir o CategoryAttribute
. Se você precisa fazer qualquer processamento, você pode usar um método estático - não testado:
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"))
{...}
Além disso - nota que, para um PropertyDescriptor
a ser utilizado, o sistema deve encontrá-lo ... as regras de resolução são:
- para
PropertyGrid
, oTypeConverter
fornece as propriedades, o padrão para as propriedades de uma instância (abaixo) - para uma instância:
-
ICustomTypeDescriptor
está marcada - Caso contrário, ele verifica a existência de um
TypeDescriptionProvider
registrada para a instância ou tipo - caso contrário, a reflexão é usado
-
- para um tipo:
- verifica a existência de um
TypeDescriptionProvider
registrado para o tipo - caso contrário, a reflexão é usado
- verifica a existência de um
- para listas:
-
IListSource
é verificada e resolveu uma lista (o processamento continua) -
ITypedList
está marcada - Caso contrário, o tipo de lista é verificada por um indexador não-objeto - ou seja
public SomeType this[int index] {get;}
- se tal for encontrado, então, as propriedades para o tipo
SomeType
são utilizados, tal como definido acima
- se tal for encontrado, então, as propriedades para o tipo
- de outra forma, se a lista não está vazia, as propriedades do primeiro exemplo (
list[0]
) são utilizados, tal como definido acima - Caso contrário, os metadados não está disponível
-