0

プロパティグリッドを、他の開発者によって作成されている一連のカスタムオブジェクトにバインドしています。これらのオブジェクトは絶えず変更および更新されているため、NotImplementedExceptionsをスローするだけのプロパティが含まれています。時々それらはのような特性を含んでいます

[廃止( "他のものを取得する代わりにthingyを使用する"、true)]

他の開発者を煩わせる代わりに。私が知っていることは後で変更されます。プロパティグリッドがこれらの特定のプロパティで壊れないようにするにはどうすればよいですか?

助けてくれてありがとう。他の開発者はそれを高く評価しています;)

4

1 に答える 1

1

デザイナーではなく、実行時に PropertyGrid をオブジェクトにバインドしようとしていると思います。winform デザイナのプロパティ グリッドを意味する場合、答えは異なります。ControlDesigner の postFilterEvents メソッドを確認する必要があります。

最も簡単な解決策は、非表示にするプロパティの BrowsableAttribute を false に設定することです。これは、他の開発者が ObsoleteAttribute を追加するときに、 も追加する必要があることを意味し[Browsable(false)]ます。しかし、あなたがもっと「自動」なものを望んでいることは理解しています。オブジェクトを PropertyGrid に渡す前に、オブジェクトのプロパティの参照可能な属性を変更するメソッドを作成できます。これは、各プロパティの TypeDescriptor を取得してから、その BrowsableAttribute を取得し、ObsoleteAttribute が存在するか例外をスローするという事実に従ってその値を設定することで実行できます (ブラウズ可能はプライベートであるため、これはリフレクションを介して行う必要があります)。 . コードは次のようになります。

    private static void FilterProperties(object objToEdit)
    {
        Type t = objToEdit.GetType();
        PropertyInfo[] props = t.GetProperties();
        // create fooObj in order to have another instance to test for NotImplemented exceptions 
        // (I do not know whether your getters could have side effects that you prefer to avoid)
        object fooObj = Activator.CreateInstance(t);
        foreach (PropertyInfo pi in props)
        {
            bool filter = false;
            object[] atts = pi.GetCustomAttributes(typeof(ObsoleteAttribute), true);
            if (atts.Length > 0)
                filter = true;
            else
            {
                try
                {
                    object tmp = pi.GetValue(fooObj, null);
                }
                catch
                {
                    filter = true;
                }
            }
            PropertyDescriptor pd = TypeDescriptor.GetProperties(t)[pi.Name];
            BrowsableAttribute bAtt = (BrowsableAttribute)pd.Attributes[typeof(BrowsableAttribute)];
            FieldInfo fi = bAtt.GetType().GetField("browsable",
                               System.Reflection.BindingFlags.NonPublic |
                               System.Reflection.BindingFlags.Instance);
            fi.SetValue(bAtt, !filter);
        }
    }

これは機能するはずですが、制限があります。編集しているクラスには少なくとも BrowsableAttribute が必要です (true または false に設定されているかどうかは関係ありません)。それ以外の場合、PropertyGrid は常に空になります。

于 2012-07-02T10:40:09.503 に答える