Добавить атрибут категории в PropertyDescriptor - PullRequest
1 голос
/ 05 мая 2009

У меня есть набор пользовательских PropertyDescriptor, который я тоже хочу добавить категории, чтобы они отображались более организованно в PropertyGrid. Я хочу, чтобы каждый тип PropertyDescriptor входил в определенную категорию.

Я пытался использовать TypeDescriptor.AddAttributes () для добавления атрибутов в существующий PropertyDescriptor, но атрибут категории не добавляется.

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.Attributes включает DisplayNameAttribute.

IntrinsicPropertyDef может отображаться с двумя различными пользовательскими PropertyDescriptors, IntrinsicPropertyDescriptor и InferedIntrinsicPropertyDescriptor. Каждый IntrinsicPropertyDescriptor должен иметь атрибут категории «Внутренние свойства», а каждый InferedIntrinsicPropertyDescriptor должен иметь атрибут категории «Предполагаемые внутренние свойства».

1 Ответ

4 голосов
/ 05 мая 2009

Я считаю Вы можете просто переопределить 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]), как определено выше
    • в противном случае метаданные недоступны
...