何とも長い表題です。
まずは、今回作るプログラムの実行結果を見てみましょう。
ボタンの外観がフラットになりました。そして、カラフルです。
ボタンに表示されているテキストも大きめですね。かつ色が白い。
また、マウスをのせると、カーソルが指型になります。
ボタンを押すと、どのボタンを押したのか、メッセージボックスで表示します。
同時に、クライアント領域にも表示されます。
さらに、フォームのサイズが縮小されて全部が表示されなくなったら、スクロールバーが出てきます。
まずは、ボタンをフラットにする方法ですが、これはButtonクラスのFlatStyleをFlatSytle.Flatに設定するだけです。FlatSytleプロパティはButtonBaseクラスからの軽症です。
public FlatStyle FlatStyle { get; set; }
戻り値のFlatStyleは、FlatStyle列挙体でメンバは次の通りです。
| メンバ | 意味 |
|---|---|
| Flat | コントロールがフラットに表示される |
| Popup | マウスでポイントされると立体的に表示される |
| Standard | 立体表示 |
| System | 外観はOSにより決定される |
次に、ボタンに自分で描画するには、ButtonクラスのOnPaintメソッドをオーバーライドします。Buttonクラスから継承したクラスを作らなかった場合はPaintイベントと自作ハンドラを関連づける必要があります。
protected override void OnPaint(PaintEventArgs pevent)
{
base.OnPaint(pevent);
string title = "ボタン";
Graphics g = pevent.Graphics;
Brush br;
switch (no)
{
case 0:
br = Brushes.Red;
title += "1";
break;
case 1:
br = Brushes.Blue;
title += "2";
break;
case 2:
br = Brushes.Brown;
title += "3";
break;
case 3:
br = Brushes.Gold;
title += "4";
break;
default:
br = Brushes.Black;
break;
}
g.FillRectangle(br,
new Rectangle(5, 5, this.Width - 10, this.Height - 10));
Font font = new Font("MS ゴシック", 14);
SizeF sz = g.MeasureString(title, font);
Single x = (this.Width - sz.Width) / 2.0F;
Single y = (this.Height - sz.Height) / 2.0F;
g.DrawString(title, font, Brushes.White, x, y);
}
背景をいろいろな色で塗るならBackColorプロパティを設定すればいいんじゃないか、と思われる方もいると思いますが、そうすると外観が図で示したようにはなりません。(ボタンの周りもその色になる、ボタン境界の内側も塗りつぶされるなど)そこで、自力でFillRectangleメソッドで矩形に塗りつぶしています。Graphics.FillRectangleメソッドには、4つのオーバーロードバージョンがあります。
public void FillRectangle ( Brush brush, Rectangle rect ) public void FillRectangle ( Brush brush, RectangleF rect ) public void FillRectangle ( Brush brush, int x, int y, int width, int height ) public void FillRectangle ( Brush brush, float x, float y, float width, float height )最初の引数は、塗りつぶすブラシを指定します。後の引数は矩形を左上隅の座標で示して、幅・高さを指定するか、Rectangleまたは、RectangleF構造体で指定します。
RectangleF構造体は第6章ですでに解説しています。Rectangle構造体は、これのint版です。
Rectangle構造体のコンストラクタはオーバーロードされていて、次のようなものがあります。
public Rectangle ( Point location, Size size ) public Rectangle ( int x, int y, int width, int height )Rectangle構造体の、主なプロパティにはX,Y(左上隅のx,y座標)、Size(この四角形のサイズ)、 Width(幅)、Height(高さ)などがあります。
Point構造体は、第3章ですでに出てきました。
さて、四角形を描画したらその上からDrawStringメソッドでテキストを描画します。
MeasureStringメソッドで、表示するテキストの計測を行います。描画開始の左上隅の座標は
Single x = (this.Width - sz.Width) / 2.0F; Single y = (this.Height - sz.Height) / 2.0F;で求まります。szは文字列の計測結果を持っているSizeF構造です。
次に、マウスでポイントされたときの挙動はButtonクラスのOnMouseHoverメソッドをバーライドして記述します。このメソッドはControlクラスからの継承です。
protected override void OnMouseHover(EventArgs e)
{
base.OnMouseHover(e);
this.Cursor = Cursors.Hand;
}
ButtonクラスのCursorプロパティを指型のカーソルに設定します。
public virtual Cursor Cursor { get; set; }
Cursorを設定するには、Cursorオブジェクトのコレクションを提供するCursorsクラスを利用すると便利です。Cursorsクラスのstaticなプロパティでよく使われると思われるものには、次のようなものがあります。
| プロパティ | 意味 |
|---|---|
| Arrow | 矢印カーソル |
| Cross | 十字カーソル |
| Default | 規定のカーソル(通常矢印) |
| Hand | 指型のカーソル |
| Help | 矢印と疑問符のカーソル |
| WaitCursor | 待機カーソル |
これらは、全部読み取り専用です。他にも多数定義されています。
では、プログラムを見てみましょう。
// button04
using System;
using System.Drawing;
using System.Windows.Forms;
class button04
{
public static string str;
public static void Main()
{
Size sz = new Size(120, 50);
MyForm mf = new MyForm(sz);
MyButton mybtn1 = new MyButton(mf,
new Point(10, 10), sz, 0);
MyButton mybtn2 = new MyButton(mf,
new Point(20 + mybtn1.Width, 10), sz, 1);
MyButton mybtn3 = new MyButton(mf,
new Point(10, 20 + mybtn1.Height), sz, 2);
MyButton mybtn4 = new MyButton(mf,
new Point(20 + mybtn1.Width, 20 + mybtn1.Height),
sz, 3);
Application.Run(mf);
}
}
class MyForm : Form
{
Size bSize;
public MyForm(Size sz)
{
Text = "猫でもわかるプログラミング";
BackColor = SystemColors.Window;
bSize = sz;
AutoScroll = true;
AutoScrollMinSize = new Size(sz.Width * 2 + 20, sz.Height * 2 + 60);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
int x = 10;
int y = bSize.Height * 2 + 30;
Font font = new Font("MS ゴシック", 14);
g.DrawString(button04.str, font, Brushes.Black,
x + AutoScrollPosition.X,
y + AutoScrollPosition.Y);
}
}
class MyButton : Button
{
int no;
public MyButton(Form parent, Point pt, Size sz, int n)
{
no = n;
Parent = parent;
Location = pt;
Size = sz;
BackColor = SystemColors.Control;
FlatStyle = FlatStyle.Flat;
}
protected override void OnClick(EventArgs e)
{
base.OnClick(e);
string str = "ボタン" + (no + 1) + "を押したね";
button04.str = str;
Parent.Invalidate();
MessageBox.Show(str, "猫でもわかるプログラミング",
MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
protected override void OnMouseHover(EventArgs e)
{
base.OnMouseHover(e);
this.Cursor = Cursors.Hand;
}
protected override void OnPaint(PaintEventArgs pevent)
{
base.OnPaint(pevent);
string title = "ボタン";
Graphics g = pevent.Graphics;
Brush br;
switch (no)
{
case 0:
br = Brushes.Red;
title += "1";
break;
case 1:
br = Brushes.Blue;
title += "2";
break;
case 2:
br = Brushes.Brown;
title += "3";
break;
case 3:
br = Brushes.Gold;
title += "4";
break;
default:
br = Brushes.Black;
break;
}
g.FillRectangle(br,
new Rectangle(5, 5, this.Width - 10, this.Height - 10));
Font font = new Font("MS ゴシック", 14);
SizeF sz = g.MeasureString(title, font);
Single x = (this.Width - sz.Width) / 2.0F;
Single y = (this.Height - sz.Height) / 2.0F;
g.DrawString(title, font, Brushes.White, x, y);
}
}
ちょっと長いですが、順番に見ていくとわかると思います。(特に、クラス間の連絡に注意して読んでみてください。)
Update 29/Oct/2006 By Y.Kumei