Вопрос

У меня есть набор пользовательских 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]) используются, как определено выше
    • в противном случае метаданные будут недоступны
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top