none
PropertyGridの内容を動的に変更 RRS feed

  • 質問

  • PropertyGridの内容を動的に変更する為このフォーラムに載っていた方法
    「PropertyウィンドウまたはPropertyGridの表示内容の動的変更 」
    http://forums.microsoft.com/msdn-ja/ShowPost.aspx?PostID=1015197&SiteID=7

    を参考にして下記のようなコードを書いたのですが、うまくいきません。

    Code Snippet
    [TypeConverter(typeof(XxxxTypeConverter))
    public class Xxxx
    {
      
    bool bFlag = false;
      
    int iNumber = 10;
      [RefreshProperties ( RefreshProperties.All ) ]
      
    public bool Flag
      {
        get { 
    return bFlag; }
        set { bFlag = value; }
      }
      [BrowsableAttribute(
    false)]
      
    public int Num
      {
        get { 
    return iNumber; }
        set { iNumber = value; }
      }
    }
    internal 
    class XxxxTypeConverter : TypeConverter
    {
      
    public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context,Object value,Attribute[] attributes)
      {
        PropertyDescriptorCollection coll = TypeDescriptor.GetProperties(value, attributes);
        
    if ((value as Xxxx).Flag)
        {
          PropertyDescriptorCollection nonBrowsableProperties = TypeDescriptor.GetProperties(value, 
    new Attribute[] { BrowsableAttribute.No });
          PropertyDescriptor pd = nonBrowsableProperties.Find(
    "Num"false);
          coll.Add(pd);
        }
        
    return coll;
      }
      
    public override bool GetPropertiesSupported(ITypeDescriptorContext context)
      {
        
    return true;
      }
    }

     

    coll.Add(pd);の部分でNotSupportedExceptionがスローされてしまいます。
    collがreadOnlyになっている為、失敗するようなのですがどうすれば良いでしょうか。
    PropertyDescriptorCollectionを作り直しての表示/非表示の動的に変更できたのですが
    可能であればDefaultValueAttribute等の属性も扱いたいと思います。

    またTypeConverterは使わず
    インスタンスの属性(BrowsableAttributeやDefaultValue等)を
    リフレクションを使って動的に変更できないかと思いましたが、
    こちらも手詰まりです。もしこちらの方法でもお分かりの方
    がいればお願い致します。
    (それが可能なのかどうなのかもわかりません。)
    宜しくお願い致します。

    2007年5月9日 17:14

回答

  •  danpa さんからの引用
    coll.Add(pd);の部分でNotSupportedExceptionがスローされてしまいます。
    collがreadOnlyになっている為、失敗するようなのですがどうすれば良いでしょうか。
     
    どうも私が動作確認していませんって書いたコードっぽいな(苦笑

     danpa さんからの引用
    PropertyDescriptorCollectionを作り直しての表示/非表示の動的に変更できたのですが
     
    これが正解だと思います。ArrayList や List`1 を利用すれば簡単ですし。
     
     danpa さんからの引用
    可能であればDefaultValueAttribute等の属性も扱いたいと思います。
     
    BrowsableAttribute と DefaultValueAttribute で大きな違いはないと思います。
    記述されているコードの BrowsableAttribute の部分を DefaultValueAttribute に変更すればよいだけだと思いますが、何か問題が発生したのでしょうか?
    # Add の呼び出しを修正した後で、という意味です
     
    2007年5月10日 13:55
  • ご回答ありがとうございます。

     K.Takaoka さんからの引用
    BrowsableAttribute と DefaultValueAttribute で大きな違いはないと思います。
    記述されているコードの BrowsableAttribute の部分を DefaultValueAttribute に変更すればよいだけだと思いますが、何か問題が発生したのでしょうか?
    # Add の呼び出しを修正した後で、という意味です

    下記コードのようにTypeDescriptor.AddAttributeを使うのかと思ったのですが、意図したようには動きませんでした。
    宜しくお願い致します。

    Code Snippet
    using System;
    using System.ComponentModel;
    using System.Data;
    
    namespace PropertyGridTest
    {
        [TypeConverter(typeof(XxxxTypeConverter))]
        public class Xxxx
        {
            bool bFlag = false;
            int num = 30;
            [RefreshProperties(RefreshProperties.All)]
            public bool Flag
            {
                get { return bFlag; }
                set { bFlag = value; }
            }
            [DefaultValueAttribute(30)]
            public int Num
            {
                get { return num; }
                set { num = value; }
            }
        }
        internal class XxxxTypeConverter : TypeConverter
        {
            public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, Object value, Attribute[] attributes)
            {
                PropertyDescriptorCollection coll = TypeDescriptor.GetProperties(value);
                PropertyDescriptorCollection ret;
                Xxxx obj = value as Xxxx;
    
                if (obj != null)
                {
                    int cnt = 0;
                    PropertyDescriptor[] pdArray = new PropertyDescriptor[0];
                    if (!obj.Flag)
                    {
                        foreach (PropertyDescriptor pd in coll)
                        {
                            if (pd.Name.Equals("Flag"))
                            {
                                System.Array.Resize(ref pdArray, cnt + 1);
                                pdArray[cnt++] = pd;
                            }
                        }
                        ret = new PropertyDescriptorCollection(pdArray, false);
                    }
                    else
                    {
                        foreach (PropertyDescriptor pd in coll)
                        {
                            if (pd.Name.Equals("Flag") || pd.Name.Equals("Num"))
                            {
                                System.Array.Resize(ref pdArray, cnt + 1);
                                pdArray[cnt] = pd;
                                if (pdArray[cnt].Name.Equals("Num"))
                                {
                                    // TypeDescriptor.AddAttributesとかも思ったのですがこのコードでは駄目でした
                                    //TypeDescriptor.AddAttributes( pd , new Attribute[] { new DefaultValueAttribute(5) } );
                                }
                                cnt++;
                            }
                        }
                        ret = new PropertyDescriptorCollection(pdArray, false);
                    }
    
                    // "Num"のDefaultValueAttributeを「5」に書き換えたいのですが方法がわかりません。
    
                    return ret;
                }
                return base.GetProperties(context, value, attributes);
            }
            public override bool GetPropertiesSupported(ITypeDescriptorContext context)
            {
                return true;
            }
        }
    }
    

     



     
    2007年5月11日 3:08
  •  danpa さんからの引用


     K.Takaoka さんからの引用
    どうも私が動作確認していませんって書いたコードっぽいな(苦笑
    そういう言い方は無いと思います。
     
    いや、元の動かないコードの投稿者は私ですよね、ってことです。

     
     danpa さんからの引用

    下記コードのようにTypeDescriptor.AddAttributeを使うのかと思ったのですが、意図したようには動きませんでした。
    宜しくお願い致します。
     
    TypeDescriptorProvider (AddAttribute) は .NET 2.0 の新機能で、前提条件や用途にあわせて使い方がかわってくるので、ちょっとおいておいたほうがいいかもしれません。TypeDescriptorProvider そのものは、目的を達成する選択肢としては誤ってはいなくて、最初の投稿に書かれている
     
     danpa さんからの引用

    またTypeConverterは使わず
    インスタンスの属性(BrowsableAttributeやDefaultValue等)を
    リフレクションを使って動的に変更できないかと思いましたが、
     
    という方向性に近いアプローチになります。読み込み終わったメタデータは改変不可能なので、リフレクションなどを利用して動的に変更することはできませんが、.NET 2.0 から TypeDescriptorProvider を利用することで、違った見え方をするようにできるようになっていると認識しています。(このあたりは実際に触ってみていないので、私の認識が間違っているかもしれないですが)
     
    TypeDescriptorProvider はおいといて話を戻して、 TypeConverter を利用する場合なのですが、SimplePropertyDescriptor を生成する TypeDescriptor.CreateProperty() を利用するのが手軽でしょう。
     
    Class1 というクラスの Value というプロパティに、表示が有効な BrowsableAttribute と 10 という既定値を設定した DefaultValueAttribute を設定する場合、

            public override PropertyDescriptorCollection GetProperties(
                    ITypeDescriptorContext context, object value, Attribute[] attributes)
            {
                List<PropertyDescriptor> newProperties = new List<PropertyDescriptor>();
     
                foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(value, attributes))
                {
                    if (pd.Name == "Value")
                    {
                        List<Attribute> newAttributes = new List<Attribute>();
     
                        // TypeDescriptor から得た Value プロパティの属性を複製する
                        foreach (Attribute attr in pd.Attributes)
                        {
                            if ((attr is BrowsableAttribute)
                             || (attr is DefaultValueAttribute))
                            {
                                // BrowsableAttribute と DefaultValueAttribute は
                                // 強制的に上書きするため複製の対象外とする
                            }
                            else
                            {
                                newAttributes.Add(attr);
                            }
                        }
     
                        // BrowsableAttribute と DefaultValueAttribute を追加
                        newAttributes.Add(BrowsableAttribute.Yes);
                        newAttributes.Add(new DefaultValueAttribute(10));
     
                        // 新しい PropertyDescriptor を作成
                        newProperties.Add(
                            TypeDescriptor.CreateProperty(typeof(Class1), pd, newAttributes.ToArray())
                        );
                    }
                    else
                    {
                        // Value プロパティ以外は何も変更しない
                        newProperties.Add(pd);
                    }
                }
     

                return new PropertyDescriptorCollection(newProperties.ToArray());
            }

     
     
    のようなかんじになります。
    # この例はフィルタをそのままバイパスしているので Browsable の部分の動作が期待
    # したように動かないきもしますが、プロパティの属性を入れ替える例ってことで。
     
    2007年5月11日 4:34
  • 詳しいご回答ありがとうございます。
    申し訳ありません。私のまったくの誤解でした。
     
     K.Takaoka さんからの引用
     という方向性に近いアプローチになります。読み込み終わったメタデータは改変不可能なので、
    勉強になります。方向が絞れそうです。
    参考にしてXxxxTypeConverterのGetPropertiesを作り直してみました。

    Code Snippet
    public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, Object value, Attribute[] attributes)
    {
        
    PropertyDescriptorCollection coll = TypeDescriptor.GetProperties(value,attributes);
        
    Xxxx obj = value as Xxxx;
        
    if (obj != null)
        {
            List<
    PropertyDescriptor> pdArray = new List<PropertyDescriptor>();
            
    foreach (PropertyDescriptor pd in coll)
            {
                
    if (pd.Name.Equals("Num") && obj.Flag )
                {
                    List<
    Attribute> newAttributes = new List<Attribute>();
                    
    foreach (Attribute attr in pd.Attributes)
                    {
                        
    if (!(attr is BrowsableAttribute)
                         && !(attr 
    is ReadOnlyAttribute)
                         && !(attr 
    is DefaultValueAttribute) )
                        {
                            newAttributes.Add(attr);
                        }
                    }
                    newAttributes.Add(
    new BrowsableAttribute(false)); // この変更ではPropertyGridに影響しないようです。
                    newAttributes.Add(new ReadOnlyAttribute(false));
                    newAttributes.Add(
    new DefaultValueAttribute(5));
                    pdArray.Add(TypeDescriptor.CreateProperty(
    typeof(Xxxx), pd, newAttributes.ToArray()));
                }
                
    else if (pd.Name.Equals("Flag"))
                {
                    pdArray.Add(pd);
                }
            }
            
    return new PropertyDescriptorCollection(pdArray.ToArray());
        }
        
    return base.GetProperties(context, value, attributes);
    }

     

     
     K.Takaoka さんからの引用
    # この例はフィルタをそのままバイパスしているので Browsable の部分の動作が期待
    # したように動かないきもしますが、プロパティの属性を入れ替える例ってことで。

    Browsableがfalseになっていると
    TypeDescriptor.GetProperties(value,attributes);
    でそのプロパティを取得できないようですね。
    それだけではなくtrueからfalseも無理でした。
    何故BrowsableAttributeのみ上手くいかないかはよくわかりません。
    自動で入ってくるComVisibleAttributeを無視する等も試したのですが結果は変わりませんでした。

    2007年5月11日 7:07
  •  danpa さんからの引用
     K.Takaoka さんからの引用
    # この例はフィルタをそのままバイパスしているので Browsable の部分の動作が期待
    # したように動かないきもしますが、プロパティの属性を入れ替える例ってことで。

    Browsableがfalseになっていると
    TypeDescriptor.GetProperties(value,attributes);
    でそのプロパティを取得できないようですね。
    それだけではなくtrueからfalseも無理でした。
    何故BrowsableAttributeのみ上手くいかないかはよくわかりません。
    自動で入ってくるComVisibleAttributeを無視する等も試したのですが結果は変わりませんでした。

     
    はい。本筋とは関係ないのではしょってしまいましたが、せっかくなので説明してみようかと思います。
    GetProperties() は、指定した属性をもつプロパティだけを取得するメソッドです。
     
    PropertyGrid から「一覧に表示するプロパティをよこせ」と言われるわけですね。
    この「一覧に表示する」という限定をしているのが、GetProperties の引数 Attribute[] attributes です。
    # PropertyGrid 以外も相手にする場合、色々な取得が発生する場合があります
     
    TypeDescriptor.GetProperties() も同様の機能を備えているので、PropertyGrid から TypeConverter.GetProperties に引き渡された attributes を、TypeDescriptor.GetProperties() に与えると、「一覧に表示するプロパティ」だけが得られることになります。
     
    つまり、元のオブジェクトに、Browsable(false) とメタデータを記載しているプロパティが存在した場合、TypeDescriptor.GetProperties(value, attributes) とやると、そのプロパティを得ることはできません。前スレッドで Browsable.No を指定して TypeDescriptor.GetProperties() を呼び出しているのは「一覧に表示しないプロパティのリストをくれ」という指定なわけですね。
     
     
    以上のようなかんじの動作ですので、ProperyGrid は TypeConverter.GetProperties() から得られた PropertyDescriptorCollection に含まれるプロパティをすべて表示します。(当然ですね? PropertyGrid は、「表示するプロパティの一覧」を取得したと思ってるんですから)
    つまり、PropertyGrid の一覧から削除したいプロパティは、TypeConverter.GetProperties() の実装で PropertyDescriptorCollection に含めない( add しない ) ように実装すればよいわけです。
     
     
    2007年5月11日 19:10
  • K.Takaoka様
    ご丁寧にご回答くださり誠にありがとうございます。
    おかげで非常に勉強になり納得できました。

    また私の勘違いによる失礼な言い回し、改めて謝りたいと思います。

    (その部分の自分の投稿について削除いたしました。)

    2007年5月12日 4:16

すべての返信

  •  danpa さんからの引用
    coll.Add(pd);の部分でNotSupportedExceptionがスローされてしまいます。
    collがreadOnlyになっている為、失敗するようなのですがどうすれば良いでしょうか。
     
    どうも私が動作確認していませんって書いたコードっぽいな(苦笑

     danpa さんからの引用
    PropertyDescriptorCollectionを作り直しての表示/非表示の動的に変更できたのですが
     
    これが正解だと思います。ArrayList や List`1 を利用すれば簡単ですし。
     
     danpa さんからの引用
    可能であればDefaultValueAttribute等の属性も扱いたいと思います。
     
    BrowsableAttribute と DefaultValueAttribute で大きな違いはないと思います。
    記述されているコードの BrowsableAttribute の部分を DefaultValueAttribute に変更すればよいだけだと思いますが、何か問題が発生したのでしょうか?
    # Add の呼び出しを修正した後で、という意味です
     
    2007年5月10日 13:55
  • ご回答ありがとうございます。

     K.Takaoka さんからの引用
    BrowsableAttribute と DefaultValueAttribute で大きな違いはないと思います。
    記述されているコードの BrowsableAttribute の部分を DefaultValueAttribute に変更すればよいだけだと思いますが、何か問題が発生したのでしょうか?
    # Add の呼び出しを修正した後で、という意味です

    下記コードのようにTypeDescriptor.AddAttributeを使うのかと思ったのですが、意図したようには動きませんでした。
    宜しくお願い致します。

    Code Snippet
    using System;
    using System.ComponentModel;
    using System.Data;
    
    namespace PropertyGridTest
    {
        [TypeConverter(typeof(XxxxTypeConverter))]
        public class Xxxx
        {
            bool bFlag = false;
            int num = 30;
            [RefreshProperties(RefreshProperties.All)]
            public bool Flag
            {
                get { return bFlag; }
                set { bFlag = value; }
            }
            [DefaultValueAttribute(30)]
            public int Num
            {
                get { return num; }
                set { num = value; }
            }
        }
        internal class XxxxTypeConverter : TypeConverter
        {
            public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, Object value, Attribute[] attributes)
            {
                PropertyDescriptorCollection coll = TypeDescriptor.GetProperties(value);
                PropertyDescriptorCollection ret;
                Xxxx obj = value as Xxxx;
    
                if (obj != null)
                {
                    int cnt = 0;
                    PropertyDescriptor[] pdArray = new PropertyDescriptor[0];
                    if (!obj.Flag)
                    {
                        foreach (PropertyDescriptor pd in coll)
                        {
                            if (pd.Name.Equals("Flag"))
                            {
                                System.Array.Resize(ref pdArray, cnt + 1);
                                pdArray[cnt++] = pd;
                            }
                        }
                        ret = new PropertyDescriptorCollection(pdArray, false);
                    }
                    else
                    {
                        foreach (PropertyDescriptor pd in coll)
                        {
                            if (pd.Name.Equals("Flag") || pd.Name.Equals("Num"))
                            {
                                System.Array.Resize(ref pdArray, cnt + 1);
                                pdArray[cnt] = pd;
                                if (pdArray[cnt].Name.Equals("Num"))
                                {
                                    // TypeDescriptor.AddAttributesとかも思ったのですがこのコードでは駄目でした
                                    //TypeDescriptor.AddAttributes( pd , new Attribute[] { new DefaultValueAttribute(5) } );
                                }
                                cnt++;
                            }
                        }
                        ret = new PropertyDescriptorCollection(pdArray, false);
                    }
    
                    // "Num"のDefaultValueAttributeを「5」に書き換えたいのですが方法がわかりません。
    
                    return ret;
                }
                return base.GetProperties(context, value, attributes);
            }
            public override bool GetPropertiesSupported(ITypeDescriptorContext context)
            {
                return true;
            }
        }
    }
    

     



     
    2007年5月11日 3:08
  •  danpa さんからの引用


     K.Takaoka さんからの引用
    どうも私が動作確認していませんって書いたコードっぽいな(苦笑
    そういう言い方は無いと思います。
     
    いや、元の動かないコードの投稿者は私ですよね、ってことです。

     
     danpa さんからの引用

    下記コードのようにTypeDescriptor.AddAttributeを使うのかと思ったのですが、意図したようには動きませんでした。
    宜しくお願い致します。
     
    TypeDescriptorProvider (AddAttribute) は .NET 2.0 の新機能で、前提条件や用途にあわせて使い方がかわってくるので、ちょっとおいておいたほうがいいかもしれません。TypeDescriptorProvider そのものは、目的を達成する選択肢としては誤ってはいなくて、最初の投稿に書かれている
     
     danpa さんからの引用

    またTypeConverterは使わず
    インスタンスの属性(BrowsableAttributeやDefaultValue等)を
    リフレクションを使って動的に変更できないかと思いましたが、
     
    という方向性に近いアプローチになります。読み込み終わったメタデータは改変不可能なので、リフレクションなどを利用して動的に変更することはできませんが、.NET 2.0 から TypeDescriptorProvider を利用することで、違った見え方をするようにできるようになっていると認識しています。(このあたりは実際に触ってみていないので、私の認識が間違っているかもしれないですが)
     
    TypeDescriptorProvider はおいといて話を戻して、 TypeConverter を利用する場合なのですが、SimplePropertyDescriptor を生成する TypeDescriptor.CreateProperty() を利用するのが手軽でしょう。
     
    Class1 というクラスの Value というプロパティに、表示が有効な BrowsableAttribute と 10 という既定値を設定した DefaultValueAttribute を設定する場合、

            public override PropertyDescriptorCollection GetProperties(
                    ITypeDescriptorContext context, object value, Attribute[] attributes)
            {
                List<PropertyDescriptor> newProperties = new List<PropertyDescriptor>();
     
                foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(value, attributes))
                {
                    if (pd.Name == "Value")
                    {
                        List<Attribute> newAttributes = new List<Attribute>();
     
                        // TypeDescriptor から得た Value プロパティの属性を複製する
                        foreach (Attribute attr in pd.Attributes)
                        {
                            if ((attr is BrowsableAttribute)
                             || (attr is DefaultValueAttribute))
                            {
                                // BrowsableAttribute と DefaultValueAttribute は
                                // 強制的に上書きするため複製の対象外とする
                            }
                            else
                            {
                                newAttributes.Add(attr);
                            }
                        }
     
                        // BrowsableAttribute と DefaultValueAttribute を追加
                        newAttributes.Add(BrowsableAttribute.Yes);
                        newAttributes.Add(new DefaultValueAttribute(10));
     
                        // 新しい PropertyDescriptor を作成
                        newProperties.Add(
                            TypeDescriptor.CreateProperty(typeof(Class1), pd, newAttributes.ToArray())
                        );
                    }
                    else
                    {
                        // Value プロパティ以外は何も変更しない
                        newProperties.Add(pd);
                    }
                }
     

                return new PropertyDescriptorCollection(newProperties.ToArray());
            }

     
     
    のようなかんじになります。
    # この例はフィルタをそのままバイパスしているので Browsable の部分の動作が期待
    # したように動かないきもしますが、プロパティの属性を入れ替える例ってことで。
     
    2007年5月11日 4:34
  • 詳しいご回答ありがとうございます。
    申し訳ありません。私のまったくの誤解でした。
     
     K.Takaoka さんからの引用
     という方向性に近いアプローチになります。読み込み終わったメタデータは改変不可能なので、
    勉強になります。方向が絞れそうです。
    参考にしてXxxxTypeConverterのGetPropertiesを作り直してみました。

    Code Snippet
    public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, Object value, Attribute[] attributes)
    {
        
    PropertyDescriptorCollection coll = TypeDescriptor.GetProperties(value,attributes);
        
    Xxxx obj = value as Xxxx;
        
    if (obj != null)
        {
            List<
    PropertyDescriptor> pdArray = new List<PropertyDescriptor>();
            
    foreach (PropertyDescriptor pd in coll)
            {
                
    if (pd.Name.Equals("Num") && obj.Flag )
                {
                    List<
    Attribute> newAttributes = new List<Attribute>();
                    
    foreach (Attribute attr in pd.Attributes)
                    {
                        
    if (!(attr is BrowsableAttribute)
                         && !(attr 
    is ReadOnlyAttribute)
                         && !(attr 
    is DefaultValueAttribute) )
                        {
                            newAttributes.Add(attr);
                        }
                    }
                    newAttributes.Add(
    new BrowsableAttribute(false)); // この変更ではPropertyGridに影響しないようです。
                    newAttributes.Add(new ReadOnlyAttribute(false));
                    newAttributes.Add(
    new DefaultValueAttribute(5));
                    pdArray.Add(TypeDescriptor.CreateProperty(
    typeof(Xxxx), pd, newAttributes.ToArray()));
                }
                
    else if (pd.Name.Equals("Flag"))
                {
                    pdArray.Add(pd);
                }
            }
            
    return new PropertyDescriptorCollection(pdArray.ToArray());
        }
        
    return base.GetProperties(context, value, attributes);
    }

     

     
     K.Takaoka さんからの引用
    # この例はフィルタをそのままバイパスしているので Browsable の部分の動作が期待
    # したように動かないきもしますが、プロパティの属性を入れ替える例ってことで。

    Browsableがfalseになっていると
    TypeDescriptor.GetProperties(value,attributes);
    でそのプロパティを取得できないようですね。
    それだけではなくtrueからfalseも無理でした。
    何故BrowsableAttributeのみ上手くいかないかはよくわかりません。
    自動で入ってくるComVisibleAttributeを無視する等も試したのですが結果は変わりませんでした。

    2007年5月11日 7:07
  •  danpa さんからの引用
     K.Takaoka さんからの引用
    # この例はフィルタをそのままバイパスしているので Browsable の部分の動作が期待
    # したように動かないきもしますが、プロパティの属性を入れ替える例ってことで。

    Browsableがfalseになっていると
    TypeDescriptor.GetProperties(value,attributes);
    でそのプロパティを取得できないようですね。
    それだけではなくtrueからfalseも無理でした。
    何故BrowsableAttributeのみ上手くいかないかはよくわかりません。
    自動で入ってくるComVisibleAttributeを無視する等も試したのですが結果は変わりませんでした。

     
    はい。本筋とは関係ないのではしょってしまいましたが、せっかくなので説明してみようかと思います。
    GetProperties() は、指定した属性をもつプロパティだけを取得するメソッドです。
     
    PropertyGrid から「一覧に表示するプロパティをよこせ」と言われるわけですね。
    この「一覧に表示する」という限定をしているのが、GetProperties の引数 Attribute[] attributes です。
    # PropertyGrid 以外も相手にする場合、色々な取得が発生する場合があります
     
    TypeDescriptor.GetProperties() も同様の機能を備えているので、PropertyGrid から TypeConverter.GetProperties に引き渡された attributes を、TypeDescriptor.GetProperties() に与えると、「一覧に表示するプロパティ」だけが得られることになります。
     
    つまり、元のオブジェクトに、Browsable(false) とメタデータを記載しているプロパティが存在した場合、TypeDescriptor.GetProperties(value, attributes) とやると、そのプロパティを得ることはできません。前スレッドで Browsable.No を指定して TypeDescriptor.GetProperties() を呼び出しているのは「一覧に表示しないプロパティのリストをくれ」という指定なわけですね。
     
     
    以上のようなかんじの動作ですので、ProperyGrid は TypeConverter.GetProperties() から得られた PropertyDescriptorCollection に含まれるプロパティをすべて表示します。(当然ですね? PropertyGrid は、「表示するプロパティの一覧」を取得したと思ってるんですから)
    つまり、PropertyGrid の一覧から削除したいプロパティは、TypeConverter.GetProperties() の実装で PropertyDescriptorCollection に含めない( add しない ) ように実装すればよいわけです。
     
     
    2007年5月11日 19:10
  • K.Takaoka様
    ご丁寧にご回答くださり誠にありがとうございます。
    おかげで非常に勉強になり納得できました。

    また私の勘違いによる失礼な言い回し、改めて謝りたいと思います。

    (その部分の自分の投稿について削除いたしました。)

    2007年5月12日 4:16