第15章 まとめて子供の面倒をみる


何とも変な表題です。



ボタンなどの子供コントロールがたくさんできたとき、まとめて面倒を見られれば便利ですね。

Formクラスには、Controlsというプロパティがあります。

public ControlCollection Controls { get; }
戻り値は、ControlCollectionです。これは、Controlクラスから派生したクラスでコントロールのコレクションを表します。

この、Addメソッドを呼び出すことにより、コントロールをコレクションに追加できます。

たとえば、次のようにして利用できます。

MyForm mf = new MyForm();
Button btn1 = new Button();
mf.Controls.Add(btn1);
これで、btn1はmfの子供となりました。今までは、btn1.Parent = mf;というようにしていましたね。また、上の例ではmf.Controls[0],...mf.Controls[n]で子供コントロールの参照を取得できます。

では、簡単なサンプルを見てみましょう。

// controlcollection01.cs

using System;
using System.Drawing;
using System.Windows.Forms;

struct MyStr
{
    public static string strTitle;
}

class controlcollection01
{
    public static void Main()
    {
        MyForm mf = new MyForm();

        Button btn1 = new Button();
        btn1.Text = "ボタン1(&1)";
        btn1.BackColor = SystemColors.Control;
        btn1.Location = new Point(10, 10);
        btn1.Click += new EventHandler(btn_Click);

        Button btn2 = new Button();
        btn2.Text = "ボタン2(&2)";
        btn2.BackColor = SystemColors.Control;
        btn2.Location = new Point(20 + btn1.Width, 10);
        btn2.Click += new EventHandler(btn_Click);

        mf.Controls.Add(btn1);
        mf.Controls.Add(btn2);

        Application.Run(mf);
    }

    static void btn_Click(object sender, EventArgs e)
    {
        Button from = (Button)sender;
        string str;

        if (from.Parent.Controls[0] == (Button)sender)
        {
            str = "ボタン1を押したね";
            MyStr.strTitle = str;
        }
        else if (from.Parent.Controls[1] == (Button)sender)
        {
            str = "ボタン2を押したね";
            MyStr.strTitle = str;
        }
        else
        {
            str = "";
            MyStr.strTitle = "";
        }
        from.Parent.Invalidate();
        MessageBox.Show(str, "猫でもわかるプログラミング",
            MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

class MyForm : Form
{
    public MyForm()
    {
        Text = "ねこでもわかるプログラミング";
        BackColor = SystemColors.Window;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        Graphics g = e.Graphics;
        Font font = new Font("MS ゴシック", 14);
        g.DrawString(MyStr.strTitle, font, Brushes.Black,
            new PointF(10.0F, this.Controls[0].Height + 20.0F));
    }
}
MyStr構造体は、ボタンがクリックされた時出されるメッセージボックスに表示されるテキストを保持します。strTitleフィールドがstaticになっている点に注意してください。

Mainメソッドでは、MyFormクラスのインスタンスmfを生成しています。

次に、ボタンbtn1, btn2を作っていますが、親は指定していません。

次に

mf.Controls.Add(btn1);
mf.Controls.Add(btn2);
として、mfの子供にbtn1とbtn2を加えています。

ボタンがクリックされたときのイベントハンドラはどちらのボタンもbtn_Clickメソッドに指定しています。

btn_Clickメソッドのsenderは、イベントの送信元を表しているので、これが、親フォームのControls[0]なら、btn1, Controls[1]なbtn2がクリックされたことを表しています。

どのボタンが押されたかがわかったら、メッセージボックスに表示する文字列を作ります。そして、その文字列をMyStr構造体のstrTitleメンバに設定します。

メッセージボックスに表示する文字列が決定したところで

from.Parent.Invalidate();
としています。fromはクリックされたボタンですから、from.Parentは親フォームですね。 親フォームに無効領域を発生させています。これで、フォームに文字列を表示させます。

次に、決定した文字列をメッセージボックスで表示しています。

MyFormクラスはFormクラスを継承しています。

OnPaintメソッドをオーバーライドして、親フォームに文字列を表示します。 ここでも、表示位置のy座標を

this.Controls[0].Height + 20.0F
としている点に注意してください。

今回は、FormクラスのControlsプロパティを使っていろいろなことをしてみました。

実行結果は、次のような感じになります。

見た目は、今までとたいして変わりありませんが、中でやっていることは、 結構進化(?)してきています。




[C# フォーム Index] [C# コンソール Index] [総合Index] [Previous Chapter] [Next Chapter]

Update 30/Oct/2006 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。