カスタムボタンの作成

twhs2008-03-07


図のように普通状態のときは白、マウスオーバーの時は黄色、押した時は青色
のように動作するボタンが欲したかったのでカスタムボタンを作成。

まず、プロジェクトから、追加、ユーザーコントロールを選択し、
新しい項目の追加画面でカスタムコントロールを選択すると
ソースが自動的に追加される。
で、このソースを元に以下のようにプロパティや関数を実装する。
要はこのOnPaintで好きなようにボタンを描画すればよいというだけ。
当たり前だがカスタム描画を行いたいので
base.OnPaint(e)を呼び出してはいけない

namespace customButton {
	public partial class CustomButton : Button {
		public CustomButton()
		{
			InitializeComponent();
		}

		override public Image BackgroundImage
		{
			get
			{
				return this.backgroundImage;
			}
			set
			{
				this.backgroundImage = value;
			}
		}

		public Image OverImage
		{
			get
			{
				return this.overImage;
			}
			set
			{
				this.overImage = value;
			}
		}	

		public Image PressedImage
		{
			get
			{
				return this.pressedImage;
			}
			set
			{
				this.pressedImage = value;
			}
		}

		protected override void OnMouseDown(MouseEventArgs e)
		{
			this.pressed = true;
			this.Invalidate();
			base.OnMouseDown(e);
		}

		protected override void OnMouseUp(MouseEventArgs e)
		{
			this.pressed = false;
			this.Invalidate();
			base.OnMouseUp(e);
		}

		protected override void OnMouseEnter(EventArgs e)
		{
			this.bInRegion = true;
			this.Invalidate();
			base.OnMouseEnter(e);
		}

		protected override void OnMouseLeave(EventArgs e)
		{
			this.bInRegion = false;
			this.Invalidate();
			base.OnMouseLeave(e);
		}

		protected override void OnPaint(PaintEventArgs e)
		{
			if (this.pressed && this.pressedImage != null) {
				e.Graphics.DrawImage(this.pressedImage, 0, 0);
			} else if (this.bInRegion && this.overImage != null) {
				e.Graphics.DrawImage(this.overImage, 0, 0);
			} else /*if (this.backgroundImage != null)*/ {
				e.Graphics.DrawImage(this.backgroundImage, 0, 0);
			}

			// Draw the text if there is any.
			if(this.Text.Length > 0)
			{
				SizeF size = e.Graphics.MeasureString(this.Text, this.Font);

				// Center the text inside the client area of the PictureButton.
				e.Graphics.DrawString(this.Text,
					this.Font,
					new SolidBrush(this.ForeColor),
					(this.ClientSize.Width - size.Width) / 2,
					(this.ClientSize.Height - size.Height) / 2);
			}

			// Draw a border around the outside of the 
			// control to look like Pocket PC buttons.
			// e.Graphics.DrawRectangle(new Pen(Color.Black), 0, 0, 
			//	this.ClientSize.Width - 1, this.ClientSize.Height - 1);

			// base.OnPaint(e);
		}
	}
}

このボタンをフォームで使用するにはツールボックスから
カスタムボタンをフォーム上にドラッグアンドドロップし、
下記のようにBackgroundImageイメージ、OverImageイメージ、PressedImageイメージを設定すれば良い

namespace customButton {
	public partial class TestForm : Form {
		public TestForm()
		{
			InitializeComponent();

			this.customBtn.BackgroundImage = MakeBitmap(System.Drawing.Color.White, customBtn.Width, customBtn.Height);
			this.customBtn.OverImage = MakeBitmap(System.Drawing.Color.Yellow, customBtn.Width, customBtn.Height);
			this.customBtn.PressedImage = MakeBitmap(System.Drawing.Color.Blue, customBtn.Width, customBtn.Height);
		}

		// Create a bitmap object and fill it with the specified color.   
		// To make it look like a custom image, draw an ellipse in it.
		Bitmap MakeBitmap(Color color, int width, int height)
		{
			Bitmap bmp = new Bitmap(width, height);
			Graphics g = Graphics.FromImage(bmp);
			g.FillRectangle(new SolidBrush(color), 0, 0, bmp.Width, bmp.Height);
			g.Dispose();

			return bmp;
		}
	}
}

デフォルトのボタンのプロパティを色々いじったり、
オーナー描画するよりはこれが一番楽。


参考URL
http://msdn2.microsoft.com/ja-jp/library/ms172532(VS.80).aspx
http://uchukamen.com/Programming1/StarButton/