まずは、今回作るプログラムの実行結果を見てみましょう。
ボタンの外観がフラットになりました。そして、カラフルです。
ボタンに表示されているテキストも大きめですね。かつ色が白い。
また、マウスをのせると、カーソルが指型になります。
ボタンを押すと、どのボタンを押したのか、メッセージボックスで表示します。
同時に、クライアント領域にも表示されます。
さらに、フォームのサイズが縮小されて全部が表示されなくなったら、スクロールバーが出てきます。
まずは、ボタンをフラットにする方法ですが、これは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