PropertyDescriptorにカテゴリ属性を追加します
-
05-07-2019 - |
質問
カテゴリを追加して、PropertyGridでより整理された方法で表示するカスタムPropertyDescriptorのセットがあります。各タイプのPropertyDescriptorを特定のカテゴリに分類します。
TypeDescriptor.AddAttributes()を使用して既存のPropertyDescriptorに属性を追加しようとしましたが、カテゴリ属性は追加されません。
CategoryAttribute intrinsicPropertyCategory = new CategoryAttribute("Intrinsic Properties");
currentDescriptor = new IntrinsicPropertyDescriptor(def);
TypeDescriptor.AddAttributes(currentDescriptor, new Attribute[] { intrinsicPropertyCategory });
また、下に示すように、PropertyDescriptorsのいずれかのコンストラクターでTypeDescriptor.AddAttributes()を使用しようとしました。しかし、それも機能しません。
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は、2つの異なるカスタムPropertyDescriptors IntrinsicPropertyDescriptorおよびInferedIntrinsicPropertyDescriptorで表示できます。すべてのIntrinsicPropertyDescriptorにはカテゴリ属性「Intrinsic Properties」が必要であり、すべてのInferedIntrinsicPropertyDescriptorにはカテゴリ属性「Inferred Intrinsic Properties」が必要です。
解決
私は Category
をオーバーライドすることができると信じています:
public override string Category { get {return "Foo";}}
他のシナリオの場合。通常、カスタムの PropertyDescriptor
を使用して、コンストラクターで属性を指定します。 CategoryAttribute
を含めるには、 Attribute []
引数を展開する必要があります。処理を行う必要がある場合は、未テストの静的メソッドを使用できます。
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]
)が使用されます(上記で定義) - それ以外の場合、メタデータは利用できません
-