none
フォームのプロパティを無効にする。 RRS feed

  • 質問

  • こんばんは。

    今日は再利用可能なフォームのプロパティについて質問です。

    あるプロジェクトにWindowsフォームを追加し、画面をデザインし、必要なプロパティを実装します。

    このフォームは再利用されることを前提にしており、

    Form1.vb(他必要なもの)をリンクしたり、あるいはDLLにして、いろんなプロジェクトで使用されます。

    その際なのですが、各プロジェクト利用される際、フォームの背景色を変えて欲しくありません。

    つまり、BackColorプロパティを無効にしたい(公開したくない)わけです。

    BackColorだけなら、(実際どうやるかわかりませんが)力技で?なんとかなるかもしれませんが、

    要は”関係ないプロパティはいじってくれるな”にしたいのです。

    (やる場合は、独自のメソッドなりを実装する)

    フォームに貼り付けたコントロールであれば、ModifiersをPrivateなりにすればいいと思うのですが、

    フォームそれ自体のプロパティを隠蔽することはできるのでしょうか?

    *自分で考えた案

    再利用可能なフォームは、それを操作するクラスでのみ操作する。

     

     

     

     

     

     

    2010年10月22日 16:30

回答

  • 基本的には無理で、Obsolete属性を付けるぐらいだと思います。

    (参考)
    継承元のパブリックメソッドを外部に隠ぺいしたい
    http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=39161&forum=7&start=8

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    2010年10月23日 0:40
    モデレータ
  • Proxyパターン?

    Formを実装したものである必要がない感じです。処理に必要なものだけを実装して共有するのでいいんじゃないでしょうか。

    2010年10月23日 2:01
  • どのような状態のものを、なにから隠したいか、ですね。

    まず、第一に、公開されてしまっている機能を継承によって失わせることはできません。(それが許された言語もありますが、クラス型のオブジェクト指向言語では稀有です。)

    Visual Studio 等のフォームデザイナから隠すだけでよい場合、デザイン時の表示設定とシリアライズ設定を変更するだけで済みます。

        // 仮想化されたプロパティの場合
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Color BackColor
        {
          get { return base.BackColor; }
          set { base.BackColor = value; }
        }
        // 非仮想プロパティの場合
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new AutoSizeMode AutoSizeMode
        {
          get { return base.AutoSizeMode; }
          set { base.AutoSizeMode = value; }
        }
    

    前者のような仮想化されているプロパティの場合、get/set の実装を変更することで、そのプロパティを実行時にも編集不可能にできますが、後者の場合には隠ぺいしているだけのため、編集を完全に止めることはできません。

    一括して複数のプロパティを変更したい場合、TypeConvereter を利用するのが手軽です。

      [TypeConverter(typeof(MyBaseFormConverter))]
      public partial class MyBaseForm : Form
      {
        public MyBaseForm()
        {
          InitializeComponent();
        }
        // 仮想化されたプロパティの場合
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Color BackColor
        {
          get { return base.BackColor; }
          set { base.BackColor = value; }
        }
        // 非仮想プロパティの場合
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new AutoSizeMode AutoSizeMode
        {
          get { return base.AutoSizeMode; }
          set { base.AutoSizeMode = value; }
        }
        // まとめて変更する場合
        internal class MyBaseFormConverter : TypeConverter
        {
          public override bool GetPropertiesSupported(ITypeDescriptorContext context)
          {
            return true;
          }
          public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
          {
            var descriptors = new List<PropertyDescriptor>();
            var source = TypeDescriptor.GetProperties(value, attributes);
            foreach (PropertyDescriptor desc in source)
            {
              // 例) W で開始するプロパティだけにする
              if (desc.Name.StartsWith("W"))
                descriptors.Add(desc);
            }
            return new PropertyDescriptorCollection(descriptors.ToArray());
          }
        }
      }
    
    この方法も、あくまで Visual Studio のデザイナの上で表示を制御しているだけです。
    2010年10月25日 0:31

すべての返信

  • 基本的には無理で、Obsolete属性を付けるぐらいだと思います。

    (参考)
    継承元のパブリックメソッドを外部に隠ぺいしたい
    http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=39161&forum=7&start=8

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    2010年10月23日 0:40
    モデレータ
  • Proxyパターン?

    Formを実装したものである必要がない感じです。処理に必要なものだけを実装して共有するのでいいんじゃないでしょうか。

    2010年10月23日 2:01
  • どのような状態のものを、なにから隠したいか、ですね。

    まず、第一に、公開されてしまっている機能を継承によって失わせることはできません。(それが許された言語もありますが、クラス型のオブジェクト指向言語では稀有です。)

    Visual Studio 等のフォームデザイナから隠すだけでよい場合、デザイン時の表示設定とシリアライズ設定を変更するだけで済みます。

        // 仮想化されたプロパティの場合
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Color BackColor
        {
          get { return base.BackColor; }
          set { base.BackColor = value; }
        }
        // 非仮想プロパティの場合
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new AutoSizeMode AutoSizeMode
        {
          get { return base.AutoSizeMode; }
          set { base.AutoSizeMode = value; }
        }
    

    前者のような仮想化されているプロパティの場合、get/set の実装を変更することで、そのプロパティを実行時にも編集不可能にできますが、後者の場合には隠ぺいしているだけのため、編集を完全に止めることはできません。

    一括して複数のプロパティを変更したい場合、TypeConvereter を利用するのが手軽です。

      [TypeConverter(typeof(MyBaseFormConverter))]
      public partial class MyBaseForm : Form
      {
        public MyBaseForm()
        {
          InitializeComponent();
        }
        // 仮想化されたプロパティの場合
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Color BackColor
        {
          get { return base.BackColor; }
          set { base.BackColor = value; }
        }
        // 非仮想プロパティの場合
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new AutoSizeMode AutoSizeMode
        {
          get { return base.AutoSizeMode; }
          set { base.AutoSizeMode = value; }
        }
        // まとめて変更する場合
        internal class MyBaseFormConverter : TypeConverter
        {
          public override bool GetPropertiesSupported(ITypeDescriptorContext context)
          {
            return true;
          }
          public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
          {
            var descriptors = new List<PropertyDescriptor>();
            var source = TypeDescriptor.GetProperties(value, attributes);
            foreach (PropertyDescriptor desc in source)
            {
              // 例) W で開始するプロパティだけにする
              if (desc.Name.StartsWith("W"))
                descriptors.Add(desc);
            }
            return new PropertyDescriptorCollection(descriptors.ToArray());
          }
        }
      }
    
    この方法も、あくまで Visual Studio のデザイナの上で表示を制御しているだけです。
    2010年10月25日 0:31