1

アプリケーションでPropertyGridを使用しています。カスタムデータ基準の実行時に、一部のプロパティの可視性と読み取り専用を変更する必要がありました。

簡単で準備ができているものは見つかりませんでしたが、実行時ReadOnlyAttributeBrowsableAttribute プロパティを次のように変更することで回避策を見つけました。

protected void SetBrowsable(string propertyName, bool value)
{
    PropertyDescriptor property = TypeDescriptor.GetProperties(GetType())[propertyName];
    BrowsableAttribute att = (BrowsableAttribute)property.Attributes[typeof(BrowsableAttribute)];
    FieldInfo cat = att.GetType().GetField("browsable", BindingFlags.NonPublic | BindingFlags.Instance);

    if (property.Attributes.Cast<Attribute>().Any(p => p.GetType() == typeof(BrowsableAttribute)))
        cat.SetValue(att, value);
}

protected void SetReadOnly(string propertyName, bool value)
{
    PropertyDescriptor property = TypeDescriptor.GetProperties(GetType())[propertyName];
    ReadOnlyAttribute att = (ReadOnlyAttribute)property.Attributes[typeof(ReadOnlyAttribute)];
    FieldInfo cat = att.GetType().GetField("isReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);

    if (property.Attributes.Cast<Attribute>().Any(p => p.GetType() == typeof(ReadOnlyAttribute)))
        cat.SetValue(att, value);
}

さて、私の問題は、これらのメソッドをどこで呼び出すべきかということです。objectこれらのメソッドを呼び出すために処理できるイベントはありますか?たぶん、インターフェースを実装することによって。

4

1 に答える 1

1

作成しない限り、property-get が呼び出されたときに発生する組み込みイベントはありません。

もちろん、カスタム ディスクリプタ (PropertyDescriptor、通常はデコレータとしてリフレクション ディスクリプタにチェーンされている) を作成すると、ディスクリプタのみ(データ バインディングなど) を介してアクセスをインターセプトし、必要なことは何でも実行できますが、任意の型 (それらを含む) に対してはあなたは書いていません)。

実行時にリフレクションを介して属性値を設定するのは...あまり良くありません。これは、主に TypeDescriptor キャッシングの偶然によって機能しています。それを行う場合は、TypeDescriptor.AddAttributes (または同様のもの) を使用することをお勧めします。ただし、カスタム モデルを実装することにより、実行しようとしていることがより適切に行われます。これを表示している場所に応じて、これは次のいずれかで実行できます。

  • カスタム TypeConverter を追加し、GetProperties をオーバーライドし、データに基づいて実行時にカスタム記述子を提供します - 主に PropertyGrid で機能します
  • オブジェクトに ICustomTypeDescriptor を実装し、GetProperties を実装し、データに基づいて実行時にカスタム記述子を提供する - ほとんどのコントロールで機能します
  • カスタム TypeDescriptionProvider を追加し、型 (TypeDescriptor.AddProvider) に関連付けて、上記のように動作する ICustomTypeDescriptor を提供します。これにより、オブジェクトがブードゥー記述子から分離されます

これらはすべてトリッキーです!最も簡単なのは TypeConverter オプションです。これは、PropertGrid について言及しているため、うまく機能します。ExpandableObjectConverter から継承し、GetProperties をオーバーライドし、必要に応じてフィルタリングし、必要に応じて読み取り専用のカスタム記述子を提供します。次に、TypeConverterAttribute を型にアタッチして、カスタム コンバーター型を指定します。

強調: .NET のこのブランチは非常に複雑で、あいまいで、使用率が低下しています。しかし、それは機能します。

于 2012-04-29T13:09:18.060 に答える