WinFormsアプリで学ぶオブジェクト指向 – シンプルなUserControlの作成

2025年2月17日

はじめに

このチュートリアルでは、UserControlを作成してオブジェクト指向の基本概念(カプセル化、継承、ポリモーフィズム)を学びます。今回はカスタムボタン「MyButton」を作成し、それを継承して「MyColoredButton」を作ることで、継承と拡張の考え方を学びます。

UserControlとは?

Windows Forms (WinForms) の UserControl は、カスタムのUIコンポーネントを作成するためのクラスです。標準のコントロール(ボタン、ラベルなど)を組み合わせて、独自の動作を持つコンポーネントを作ることができます。

UserControlの利点

  • 再利用可能: 一度作成すれば、異なるフォームやプロジェクトで使用可能。
  • カプセル化: 内部のロジックを隠蔽し、特定のインターフェースを提供。
  • カスタマイズ可能: 既存のUI要素を組み合わせ、独自の機能を追加できる。

UserControlの作成

ツールボックスを使って簡単に作成する

  1. Visual Studio で新しい Windows Forms アプリ を作成します。
  2. ソリューションエクスプローラー でプロジェクトを右クリックし、追加新しい項目 を選択。
  3. ユーザーコントロール(UserControl Windows フォーム) を選択し、MyButton.cs として追加します。
  4. ツールボックス から ボタン(Button) をドラッグ&ドロップして配置します。
  5. プロパティウィンドウText"Click Me" に変更。
  6. イベント(Events)タブClick イベント をダブルクリックし、以下のコードを記述。
private void button1_Click(object sender, EventArgs e)
{
    MessageBox.Show("ボタンがクリックされました!");
}

カスタムプロパティを追加(カプセル化)

MyButton.csコード を開き、以下のように編集します。

public partial class MyButton : UserControl
{
    public MyButton()
    {
        InitializeComponent();
    }

    public string ButtonText
    {
        get 
        { 
            return button1.Text; 
        }
        set 
        {
            button1.Text = value;
        }
    }
}

継承を使ってカスタマイズする(継承とポリモーフィズム)

MyButton を継承して MyColoredButton を作成し、ボタンの色を変更できるようにします。

public class MyColoredButton : MyButton
{
        public Color ButtonColor
        {
            get
            {
                return (Controls["button1"] as Button).BackColor;
            }
            set
            {
                (Controls["button1"] as Button).BackColor = value;
            }
        }
}

MyColoredButton クラスは MyButton を継承し、ボタンの色 (BackColor) を取得・設定できるようにしたものです。

1. クラスの継承

public class MyColoredButton : MyButton
  • MyColoredButtonMyButton クラスを継承しており、MyButton の機能を拡張しています。

2. ButtonColor プロパティ

public Color ButtonColor
  • ButtonColorColor 型のプロパティで、get でボタンの背景色を取得し、set で背景色を設定します。
(1) get アクセサ
get
{
    return (Controls["button1"] as Button).BackColor;
}
  • Controls["button1"] でコントロールコレクションから "button1" という名前のコントロールを取得。
  • as ButtonButton 型にキャストし、BackColor を取得。
(2) set アクセサ
set
{
    (Controls["button1"] as Button).BackColor = value;
}
  • Controls["button1"] から Button を取得。
  • BackColorvalue をセット。

前提条件

  • MyButtonControl を継承しており、Controls コレクションを持っている必要がある。
  • "button1" という名前の Button コントロールが Controls に追加されている。

考えられる問題点

  1. Controls["button1"]null の場合
    • "button1" という名前の Button が存在しないと null になり、null 参照エラー (NullReferenceException) になる可能性がある。
    • 対策: null チェックを追加する。
get
{
    var btn = Controls["button1"] as Button;
    return btn != null ? btn.BackColor : Color.Empty;
}
set
{
    var btn = Controls["button1"] as Button;
    if (btn != null) btn.BackColor = value;
}
  1. MyButtonControls が存在しない場合
    • ControlsControl クラス由来のプロパティであるため、MyButtonControl を継承していなければエラーになる。
  2. キャストの問題
    • "button1"Button 以外のコントロールだった場合、as Button の結果は null になり、BackColor にアクセスするとエラーになる。

まとめ

  • MyColoredButtonMyButton を継承し、button1 の背景色を変更できるプロパティ ButtonColor を提供する。
  • "button1"Controls に存在しない場合、null 参照エラーが発生する可能性があるため、適切なエラーハンドリングが必要。

ソリューションをビルドします

作成したユーザーコントロールをツールボックスに反映させます

フォームに追加して動作を確認

ツールボックスを使う場合

  1. ツールボックス を開き、MyButton が追加されていることを確認。
  2. フォーム (Form1.cs) にドラッグ&ドロップして配置。
  3. プロパティウィンドウButtonText"カスタムボタン" に変更。

コードで追加する場合

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        MyColoredButton myButton = new MyColoredButton()
        {
            ButtonText = "カスタムボタン",
            ButtonColor = Color.Coral,
            Location = new Point(50, 50),
            Size = new Size(150, 50)
        };

        this.Controls.Add(myButton);
    }
}

まとめ

  • UserControlとは: 再利用可能なカスタムUIコンポーネント。
  • ツールボックスを活用: ドラッグ&ドロップで簡単に作成可能。
  • カプセル化: ButtonTextButtonColor のプロパティを通じて、内部の値を保護。
  • 継承: MyButtonMyColoredButton が拡張。
  • ポリモーフィズム: MyColoredButtonMyButton として振る舞うことが可能。

このように、ツールボックスを活用すれば、より直感的にUserControlを作成できます。