|
多少面倒で、いくらか型記述に関する知識が必要ですよ。 具体的には以下のような実装手順になります。
変更したいプロパティ(上記例の AAA)を持っているクラス(上記例の ZZZ)に TypeConverter 属性を付ける。 ZZZ には Browsable(False) なプロパティ AAAReadOnly を用意。
TypeConverter から派生したクラス(仮に ZZZConverter とする)を作成する。ZZZ の TypeConverter 属性の引数にはこの ZZZConverter を指定する。 GetPropertiesSupported をオーバーライドし、True を返させる。 GetProperties をオーバーライドし、適切な PropertyDescriptorCollection を返す(後述)。
PropertyDescriptor から派生したクラス(仮に AAAPropertyDescriptor とする)を作成する。直接派生するのは面倒なので、ZZZConverter のネストクラスとして SimplePropertyDescriptor から派生するのが便利。 AAAPropertyDescriptor のコンストラクタの引数に ZZZ を用意し、渡された ZZZ をフィールドに保存しておく。 GetValue と SetValue をオーバーライドし、適切な処理を実装する(引数 component を ZZZ にキャストし、GetValue ならその AAA を返し、SetValue ならその AAA に value を AAA の型にキャストして代入する)。 IsReadOnly をオーバーライドし、フィールドの ZZZ の AAAReadOnly を返す。
さて、GetProperties ですが、次のような実装でいいでしょう。
TypeDescriptor.GetProperties(Object, Attribute(), Boolean) を使ってカスタムされていないオリジナルの PropertyDescriptorCollection を取得する。 この PropertyDescriptorCollection と同数の PropertyDescriptor 配列を作成する。 For ループで、PropertyDescriptorCollection の中身をそれぞれ PropertyDescriptor 配列に移す。 ただし、Name が AAA の PropertyDescriptor のみ、AAAPropertyDescriptor を代わりに PropertyDescriptor 配列に格納する。 PropertyDescriptor 配列から PropertyDescriptorCollection を作成して返す。
あとは、PropertyGrid の SelectedObject に渡した ZZZ インスタンスの AAAReadOnly を変更した上で PropertyGrid の Refresh を呼び出せば、読み取り専用かどうかが切り替わるようになります。
|