トップ回答者
フォームのプロパティを無効にする。

質問
-
こんばんは。
今日は再利用可能なフォームのプロパティについて質問です。
あるプロジェクトにWindowsフォームを追加し、画面をデザインし、必要なプロパティを実装します。
このフォームは再利用されることを前提にしており、
Form1.vb(他必要なもの)をリンクしたり、あるいはDLLにして、いろんなプロジェクトで使用されます。
その際なのですが、各プロジェクト利用される際、フォームの背景色を変えて欲しくありません。
つまり、BackColorプロパティを無効にしたい(公開したくない)わけです。
BackColorだけなら、(実際どうやるかわかりませんが)力技で?なんとかなるかもしれませんが、
要は”関係ないプロパティはいじってくれるな”にしたいのです。
(やる場合は、独自のメソッドなりを実装する)
フォームに貼り付けたコントロールであれば、ModifiersをPrivateなりにすればいいと思うのですが、
フォームそれ自体のプロパティを隠蔽することはできるのでしょうか?
*自分で考えた案
再利用可能なフォームは、それを操作するクラスでのみ操作する。
回答
-
どのような状態のものを、なにから隠したいか、ですね。
まず、第一に、公開されてしまっている機能を継承によって失わせることはできません。(それが許された言語もありますが、クラス型のオブジェクト指向言語では稀有です。)
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 を利用するのが手軽です。
この方法も、あくまで Visual Studio のデザイナの上で表示を制御しているだけです。[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()); } } }
- 回答としてマーク アースワーム 2010年10月27日 11:58
すべての返信
-
どのような状態のものを、なにから隠したいか、ですね。
まず、第一に、公開されてしまっている機能を継承によって失わせることはできません。(それが許された言語もありますが、クラス型のオブジェクト指向言語では稀有です。)
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 を利用するのが手軽です。
この方法も、あくまで Visual Studio のデザイナの上で表示を制御しているだけです。[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()); } } }
- 回答としてマーク アースワーム 2010年10月27日 11:58