カウンタ

カスタムコントロールによる独自のコントロールを作成する

ページ更新日:2008/ 7/ 6
概要
 カスタムコントロールとは、既存のコントロールを配置するのではなく、独自に描画などを行って作成できるコントロールです。最低限の機能だけを継承して作成するので、独自性のあるコントロールを作成できたり、余分な機能を省いて最適なコントロールを作成できたりします。サンプルでは、クリックした個所の座標を取得することができるコントロールを作成します。
カスタムコントロールによる独自のコントロールを作成する
動作確認バージョン
.NET Compact Framework バージョン
  • 2.0
  • 3.5
Visual Studio バージョン
  • 2008
Windows Mobile SDK バージョン
  • 5
Tips

カスタムコントロールを追加する

新しい項目の追加 カスタムコントロールを作るにはプロジェクトにカスタムコントロールを追加する必要があります。

 追加先のプロジェクトを右クリックして、「追加」→「新しい項目」と選択します。

新しい項目の追加ダイアログ ダイアログが開いたら、カテゴリから「Windows Forms」を選択し、テンプレートから「カスタム コントロール」を選択します。

 クリックした位置を取得できるコントロールを作成するので、「ファイル名」に「PointSetter」と入力します。(拡張子は自動で付加されます)

 設定が終わったら「追加」ボタンを押します。

カスタムコントロール作成後 カスタムコントロールを作成すると、デザイナ画面が開きます。

 このデザイナ画面にはコントロールが置けますが、今回は使用しません。置いたとしても実際にはコードを入力しないとコントロールを配置できないので注意が必要です。

カスタムコントロール内の処理を実装する

カスタムコントロール作成後まず、コントロールをクリックしたときに位置を取得するために、「MouseDown」イベントを作成します。ダブルクリックで作成できます。

 CreateCustomControl クラスにマウスでクリックしたときの位置を記憶されるためのフィールドとプロパティを追加します。

/// <summary>
/// 選択座標
/// </summary>
private Point position = Point.Empty;
/// <summary>
/// 選択座標
/// </summary>
public Point Position
{
    get { return this.position; }
    set { this.position = value; }
}

 MouseDown イベントでマウスをクリックしたときの座標を記憶するようにします。また、位置が更新されるので、コントロールの再描画も行います。(ここではあえてフィールドに値をセットするのではなく、プロパティを経由してセットしています

/// <summary>
/// マウスのボタンを押したとき
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PointSetter_MouseDown(object sender, MouseEventArgs e)
{
    // マウスの位置を記憶
    this.Position = new Point(e.X, e.Y);

    // 再描画
    this.Invalidate();
}

 続いて描画処理のコードを書きます。クリックした位置を赤丸で表示し、コントロールの枠を黒線で描きます。

/// <summary>
/// 描画処理
/// </summary>
/// <param name="pe"></param>
protected override void OnPaint(PaintEventArgs pe)
{
    // TODO: カスタム描画コードをここに追加します
    Graphics g = pe.Graphics;

    int ellipseRadius = 4;

    // 赤丸の描画
    using (Brush brush = new SolidBrush(Color.Red))
    {
        g.FillEllipse(brush, this.position.X - ellipseRadius,
                             this.position.Y - ellipseRadius,
                             ellipseRadius * 2,
                             ellipseRadius * 2);
    }

    // 枠の描画
    using (Pen pen = new Pen(Color.Black))
    {
        Rectangle frameRectangle = pe.ClipRectangle;
        frameRectangle.Width--;
        frameRectangle.Height--;
        g.DrawRectangle(pen, frameRectangle);
    }

    // Calling the base class OnPaint
    base.OnPaint(pe);
}

カスタムコントロールを配置する

作成したコントロールがツールボックスに表示される 作成したコントロールは実際に Form に配置して確認しましょう。

 コントロールを作成してビルドを行うと、ツールボックスに作成したコントロールが表示されます。これをフォームに配置します。

配置したコントロール 右のようにデザイナに配置できると思います。

コントロールの操作 デバッグ実行をして実際にコントロールをクリックしてみると、その場所に赤丸が表示されると思います。

作成したコントロールにイベントを登録できるようにする

 実際にユーザーコントロールでクリックした場所に赤丸が描画されましたが、あくまでコントロールの中での話ですので、このままではあまり使い道がありません。今度はこのコントロールで位置が変化したときに、フォーム上のラベルに座標を表示できるようにしてみましょう。

イベントを取得する

テキストボックスの配置 座標を表示するためのラベルを配置しておきます。

ColorChanged イベント PointSetter コントロールイベントを見てみると、先ほど追加したイベントが表示されていると思います。この項目をダブルクリックして Form にイベントを追加します。

※イベントの属性などをまだ設定していないので説明文がなく、カテゴリも「その他」になっています。

 イベントコードが追加されたら、ラベルに座標が表示されるようにします。

/// <summary>
/// 座標指定コントロールの値が変化したとき
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void pointSetter1_PositionChanged(object sender, EventArgs e)
{
    Point position = this.pointSetter1.Position;
    this.label1.Text = "(" + position.X + ", " + position.Y + ")";
}

実行 では実際に実行してみましょう。座標がラベルに表示されていたら成功です。

プロジェクト ダウンロード
ファイル サイズ .NET Compact Frameworkバージョン 作成日
windows_mobile_createcustomcontrol.zip 13.6 KB 2.0 2008/07/06
コード

MainForm.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace CreateCustomControl
{
    /// <summary>
    /// メインフォーム
    /// </summary>
    public partial class MainForm : Form
    {
        /// <summary>
        /// コンストラクタ
        /// </summary>
        public MainForm()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 座標指定コントロールの値が変化したとき
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pointSetter1_PositionChanged(object sender, EventArgs e)
        {
            Point position = this.pointSetter1.Position;
            this.label1.Text = "(" + position.X + ", " + position.Y + ")";
        }
    }
}

PointSetter .cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace CreateCustomControl
{
    /// <summary>
    /// 座標指定コントロール
    /// </summary>
    public partial class PointSetter : Control
    {
        /// <summary>
        /// 座標の値が変化したときにイベントが発生します。
        /// </summary>
        public event EventHandler PositionChanged = null;
        
        
        /// <summary>
        /// 選択座標
        /// </summary>
        private Point position = Point.Empty;
        /// <summary>
        /// 選択座標
        /// </summary>
        public Point Position
        {
            get { return this.position; }
            set
            {
                this.position = value;

                // 座標の値変更イベント
                if (this.PositionChanged != null)
                {
                    this.PositionChanged(this, new EventArgs());
                }
            }
        }


        /// <summary>
        /// コンストラクタ
        /// </summary>
        public PointSetter()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 描画処理
        /// </summary>
        /// <param name="pe"></param>
        protected override void OnPaint(PaintEventArgs pe)
        {
            // TODO: カスタム描画コードをここに追加します
            Graphics g = pe.Graphics;

            // 丸の半径
            int ellipseRadius = 4;

            // 赤丸の描画
            using (Brush brush = new SolidBrush(Color.Red))
            {
                g.FillEllipse(brush, this.position.X - ellipseRadius,
                                     this.position.Y - ellipseRadius,
                                     ellipseRadius * 2,
                                     ellipseRadius * 2);
            }

            // 枠の描画
            using (Pen pen = new Pen(Color.Black))
            {
                Rectangle frameRectangle = pe.ClipRectangle;
                frameRectangle.Width--;
                frameRectangle.Height--;
                g.DrawRectangle(pen, frameRectangle);
            }

            // Calling the base class OnPaint
            base.OnPaint(pe);
        }

        /// <summary>
        /// マウスのボタンを押したとき
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PointSetter_MouseDown(object sender, MouseEventArgs e)
        {
            // マウスの位置を記憶
            this.Position = new Point(e.X, e.Y);

            // 再描画
            this.Invalidate();
        }
    }
}
更新履歴
更新日時 更新内容
2008/07/06 ページ作成
広告
Copyright (C) since 2005 Yuichi Onodera (おのでら), All rights reserved.