解説

実例で学ぶWindowsプログラミング

第2回 継承と属性プログラミングで実現するRAD開発 

デジタルアドバンテージ
2004/12/11
Page1 Page2 Page3 Page4

属性プログラミングの実践

 新規にコントロールを作成した場合、VS.NETでのデザイン時にそのコントロールをドラッグ&ドロップで配置し、さらに[プロパティ]ウィンドウでそのコントロールのプロパティを変更して、コントロールの表示や動作をカスタマイズできるようにしておけば便利だ。.NETの言語機能である「属性」を利用すると、このような[プロパティ]ウィンドウへの表示を制御することなどが簡単にできる。以下では、属性の代表的な利用方法について、今回のサンプル・アプリケーションの開発例を通して、簡単に説明する。

■プロパティ属性の設定

 上記のDrawPanelメソッド内のコードに文字列を描画する処理があるが、その文字列にはTitleTextプロパティの値が使われている。このTitleTextプロパティは、基本クラスにもともと存在するものではなく、派生クラスで新たに追加されたものだ。その実装コードは以下のようになっている。

private string panelTitleText = "";

[Category("表示"),
Description("パネル上に表示するテキストです。"),
DefaultValue("")]
public string TitleText
{
  get
  {
    return this.panelTitleText;
  }
  set
  {
    this.panelTitleText = value;
    this.Invalidate();
  }
}
パネルのタイトル・テキストを取得・設定するためのTitleTextプロパティ(C#)
プロパティ定義の手前に記述されている“[”〜“]”で区切られた部分は、VS.NETの[プロパティ]ウィンドウに表示方法を指定するための属性である。それぞれの属性は、「〜Attributeクラス」で定義されている。例えば、「Category」属性は「CategoryAttribute」クラスを意味しているが、その「Attribute」の記述は省略できる。

 TitleTextプロパティのソース・コードで注目してほしいのは、プロパティ定義の手前に記述されている“[”〜“]”で区切られた部分だ。これは、「属性」と呼ばれる.NETの言語機能の1つで、ここで記述した属性により、VS.NETでのデザイン時に表示される[プロパティ]ウィンドウの表示方法を指定・変更したりできる。

 上記コードにある属性のそれぞれの意味は、次の表のとおりだ。

属性 説明
Category これを指定すると、そのプロパティが[プロパティ]ウィンドウのどの分類に所属するかを指定できる。例えば、属性のパラメータに「表示」と記述すれば、そのプロパティは「表示」カテゴリに分類されることになる。ここで「Appearance」と英語表記した場合も、自動的に「表示」カテゴリに分類される。このほかの分類項目には、例えば「動作」(Behavior)「デザイン」(Design)などがある
Description [プロパティ]ウィンドウの[説明]領域に表示される記述
DefaultValue プロパティの既定値
TitleTextプロパティで指定している属性の内容
表にある「属性」の記述では、「Attribute」を省略しているので注意してほしい。例えば、「Category」は「CategoryAttribute」から「Attribute」が省略されたもの。

 上記のような属性を付加したTitleTextプロパティを定義した場合、VS.NETの[プロパティ]ウィンドウは次の画面例のように表示される(なおコントロールのプロパティを新規実装すると、そのプロパティは自動的に[プロパティ]ウィンドウに表示されることになる)。

属性指定によりカスタマイズされた[プロパティ]ウィンドウ上の表示内容
新たに追加したプロパティに対して左記表のような属性指定を行うと、[プロパティ]ウィンドウではこのような表示になる。
  Category属性の指定に基づきTitleTextプロパティは[表示](Appearance)カテゴリに分類される。
  Description属性に指定した文章(この例では「パネル上に表示するテキストです。」)が説明領域に表示される。
  DefaultValue属性に指定した値(この例では空文字)がプロパティの既定値として自動設定される。

■クラス属性の指定

 さらにMenuPanelクラスの定義では、次のコード例のように属性を指定している。

[ToolboxBitmap(typeof(Panel))]
public class MenuPanel : System.Windows.Forms.Panel
MenuPanelクラスの属性指定(C#)

 ToolboxBitmap属性は、[ツールボックス]ウィンドウに表示されるアイコンを指定するためのものだ(この例では、Panelコントロールと同じアイコンを設定している)。

 以上のようにしてMenuPanelコントロールが[プロパティ]ウィンドウで適切に表示できるように実装した。MenuPanelコントロールの残りの実装内容の解説は割愛させていただく。詳細は次のリンクをクリックして、ソース・コードを参照していただきたい。

■拡張ボタン・コントロール「MenuButtonコントロール」の作成

 それでは、次に拡張ボタン・コントロールの作成を行おう。ボタンの作成手順も、パネルの場合とまったく同じである。

 拡張Windowsコントロールを新たに作成するために、カスタム・コントロールを「MenuButton.cs」というファイル名で作成し、継承元のクラスを ControlクラスからButtonコントロール(System.Windows.Forms名前空間)に書き換える。後はMenuPanelコントロールの場合と同じようにOnPaintメソッドをオーバーライドして描画処理を独自のものに差し替えればよい(MenuButtonコントロールの描画処理の実装内容は割愛させていただく)。

■クラス属性の指定による[プロパティ]ウィンドウ上への非表示化

 MenuButtonコントロールは、クラスの属性指定がMenuPanelコントロールとまったく同じではない。ToolboxBitmap属性に加えて、Designer属性というものをさらに追加している。

 このDesigner属性は、Windowsフォーム・デザイナ上での表示をカスタマイズするためのものだ。ここでは、この属性によりデザイン時に一部のプロパティの項目が[プロパティ]ウィンドウに表示されないようにする。

 以下のコードでは、Designer属性のパラメータとして「typeof(MenuButton.MenuButtonDesigner)」を指定しているが、これは、このMenuButtonコントロールの具体的なカスタマイズ内容が、「MenuButton.MenuButtonDesigner」というクラスで実装されていることを示している。このパラメータに指定するクラスは、必ずControlDesignerクラス(System.Windows.Forms.Design名前空間)を継承したクラスである必要がある。

 「MenuButton.MenuButtonDesigner」というクラス名を見て分かるように、本稿ではこのクラスを入れ子クラスとして(つまり、MenuButtonクラスの中にMenuButtonDesignerクラスを)実装した。

 このMenuButton.MenuButtonDesignerクラスの具体的な実装内容は次のとおりだ(なおこのクラスをビルドするには、あらかじめ「System.Design.dll」への[参照の追加]が必要)。

using System.Windows.Forms.Design;

[ToolboxBitmap(typeof(Button))]
[Designer(typeof(MenuButton.MenuButtonDesigner))]
public class MenuButton : System.Windows.Forms.Button
{
  ……中略……
 

  // MenuButtonコントロールのデザイナ上の表示をカスタマイズする

  internal class MenuButtonDesigner : ControlDesigner
  {
    protected override void PostFilterProperties(IDictionary Properties)
    {
      // 次のプロパティはデザイナでは非表示にする
      Properties.Remove("FlatStyle");
      Properties.Remove("BackgroundImage");
      Properties.Remove("Image");
      Properties.Remove("ImageAlign");
      Properties.Remove("ImageIndex");
      Properties.Remove("ImageList");
    }
  }
}
MenuButtonクラスの属性指定とデザイナ表示をカスタマイズするクラス(C#)
Windowsデザイナ上での表示のカスタマイズ方法を指定するMenuButtonDesignerクラスをMenuButtonクラス内の入れ子クラスとして実装している。

 上記のMenuButtonDesignerクラスのコードでは、PostFilterPropertiesメソッドをオーバーライドして、そのメソッド・パラメータに引き渡されるIDictionaryオブジェクト(System.Collections名前空間)のRemoveメソッドを繰り返し呼び出している。

 このRemoveメソッドを使うと、そのメソッドのパラメータに指定した既存のプロパティが[プロパティ]ウィンドウに表示されないようになる。つまりこのコード例では、「FlatStyle」「BackgroundImage」「Image」「ImageAlign」「ImageIndex」「ImageList」などのプロパティが[プロパティ]ウィンドウに表示されないようにしている。なお、このようにプロパティを非表示にしている理由は、これらのプロパティに対応するMenuButtonコントロールの機能を本サンプル・プログラムでは実装していないためである。

 上記コードの属性指定を行ったMenuButtonコントロールは、[プロパティ]ウィンドウで次のように表示される(分かりやすいように、通常のButtonコントロールを並べて比べてみた)。

Buttonコントロール(左)とMenuButtonコントロール(右)のプロパティ表示
MenuButtonコントロールではDesigner属性の指定により、「BackgroundImage」「FlatStyle」「Image」「ImageAlign」「ImageIndex」「ImageList」などのプロパティが非表示になっている。

 以上でMenuButtonコントロールの作成は完了したものとする。残りの実装内容の説明は割愛させていただく。より詳細なMenuButtonコントロールの実装内容は、次のリンクをクリックして、ソース・コードを参照してほしい。

 以上で独自コントロールはすべてそろったので、仕上げとしてこれらのコントロールをフォーム上に配置して、本稿冒頭で紹介したスタート・メニュー画面を構築しよう。


 INDEX
  解説:実例で学ぶWindowsプログラミング
  第2回 継承と属性プログラミングで実現するRAD開発
    1.スタート・メニュー画面の構築について
    2.拡張Windowsコントロールの作成
  3.属性プログラミングの実践
    4.拡張Windowsコントロールの利用方法

更新履歴
【2005/3/15】本記事の一部に以下のような誤りがありました。お詫びして訂正させていただきます。

このMenuButton.MenuButtonDesignerクラスの具体的な実装内容は次のとおりだ。
このMenuButton.MenuButtonDesignerクラスの具体的な実装内容は次のとおりだ(なおこのクラスをビルドするには、あらかじめ「System.Design.dll」への[参照の追加]が必要)。

VB.NETのサンプル・コード(winexp02_05.vb)

<ToolboxBitmap(Type.GetType(Button))> _
<Designer(Type.GetType(MenuButton.MenuButtonDesigner))> _
<ToolboxBitmap(GetType(System.Windows.Forms.Button)), _
Designer(GetType(MenuButton.MenuButtonDesigner))> _

インデックス・ページヘ  「解説:実例で学ぶWindowsプログラミング」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH