Добавьте атрибут категории в PropertyDescriptor
-
05-07-2019 - |
Вопрос
У меня есть набор пользовательских PropertyDescriptor, в которые я также хочу добавить категории, чтобы они отображались более организованно в PropertyGrid.Я хочу, чтобы каждый тип PropertyDescriptor относился к определенной категории.
Я пытался использовать TypeDescriptor.addAttributes() для добавления атрибутов к существующему PropertyDescriptor, но атрибут category не добавлен.
CategoryAttribute intrinsicPropertyCategory = new CategoryAttribute("Intrinsic Properties");
currentDescriptor = new IntrinsicPropertyDescriptor(def);
TypeDescriptor.AddAttributes(currentDescriptor, new Attribute[] { intrinsicPropertyCategory });
Я также пробовал использовать TypeDescriptor.addAttributes() в конструкторе для одного из моих PropertyDescriptors, как показано ниже.Но это тоже не работает.
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 });
}
Я бы предпочел не тратить время на подробное описание того, почему я делаю то, что я делаю.Но в приведенном выше примере IntrinsicPropertyDef - это класс, который определяет свойство, включающее Имя, отображаемое имя и Тип.Итак, propDef.Атрибуты включают атрибут DisplayNameAttribute .
IntrinsicPropertyDef может отображаться с двумя различными пользовательскими PropertyDescriptors IntrinsicPropertyDescriptor и InferedIntrinsicPropertyDescriptor.Каждый IntrinsicPropertyDescriptor должен иметь атрибут категории "Внутренние свойства", и каждый выведенный intrinsicpropertydescriptor должен иметь атрибут категории "Выведенные внутренние свойства".
Решение
Я верьте вы можете просто переопределить Category
:
public override string Category { get {return "Foo";}}
Для других сценариев;в общем, с обычаем PropertyDescriptor
, вы указываете атрибуты в конструкторе.Вам нужно будет расширить Attribute[]
аргумент для включения CategoryAttribute
.Если вам нужно выполнить какую-либо обработку, вы можете использовать статический метод - непроверенный:
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"))
{...}
Также - обратите внимание, что для PropertyDescriptor
чтобы быть использованным, система должна найти его...правила разрешения таковы:
- для
PropertyGrid
, тот самыйTypeConverter
предоставляет свойства, по умолчанию соответствующие свойствам для экземпляра (ниже) - для примера:
ICustomTypeDescriptor
проверяется- в противном случае он проверяет наличие зарегистрированного
TypeDescriptionProvider
для экземпляра или типа - в противном случае используется отражение
- для типа:
- он проверяет наличие зарегистрированного
TypeDescriptionProvider
для данного типа - в противном случае используется отражение
- он проверяет наличие зарегистрированного
- для списков:
IListSource
проверяется и преобразуется в список (обработка продолжается)ITypedList
проверяется- в противном случае тип списка проверяется на наличие индексатора, не являющегося объектом, т. е.
public SomeType this[int index] {get;}
- если таковой найден, то свойства для данного типа
SomeType
используются, как определено выше
- если таковой найден, то свойства для данного типа
- в противном случае, если список не пуст, свойства первого экземпляра будут изменены. (
list[0]
) используются, как определено выше - в противном случае метаданные будут недоступны