C# Programming

Image

グラデーションのあるボタンを作る


開発環境: Visual Studio 2003
Image
おおもとのサンプルコードは、Microsoftのチュートリアル にあります。説明はそちらをご覧ください。

以下のサンプルコードは、Microsoftのチュートリアルをベースにして、若干の修正をしています。
見てわかるように、もともとのサンプルに対して、グラデーションの斜めの方向が逆になっています。
そのために、LinearGradientBrush のコンストラクターを呼び出しているところで、Angle を渡すように変更しています。

今回手を加えているのは2点です。
1、角度を変更できるようにするために、Angle プロパティを追加しています。
2、マイクロソフトのサンプルコードでは、ボタンのボーダーを正しく表示するためにペイントする範囲を -1, -1 にしているが、それでは不十分で -2, -2 にしています。
GradientButton をビルドした後に、ツールボックスに追加します。
これにより、通常のボタンと同じようにツールボックスからのドラッグアンドドロップ、プロパティウィンドウからの値の修正ができます。
下図参照。
Image
ついでに、Form 側でタイマーによりアングルを変えることにより、ボタンの色がグリグリ回るForm1.cs を載せておきます。
だから何なのという突っ込みは却下。
日付修正履歴
5/25グリグリ回るボタンを表示するダイアログ。
5/12初期バージョン作成
以下、ソースコード
GradientButton.cs
Form1.cs

GradientButton.cs

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

namespace Uchukamen.Forms
{
        /// <summary>
        /// GradientButton の概要の説明です。
        /// </summary>
        public class GradientButton : System.Windows.Forms.Button
        {
                // members to hold our color settings
                private Color startColor;
                private Color endColor;
                private float angle;
            
                // we'll need this to paint the text
                private static StringFormat format = new StringFormat();

                public GradientButton() : base() 
                {
                        // initialize our colors 
                        startColor = SystemColors.InactiveCaption;
                        endColor = SystemColors.ActiveCaption;
                        format.Alignment = StringAlignment.Center;
                        format.LineAlignment = StringAlignment.Center;
                        angle = 0;
                }
            
                public Color EndColor 
                {
                        get 
                        {
                                return this.endColor;
                        }
                        set 
                        {
                                this.endColor = value;
                                // cause a repaint if necessary
                                if (this.IsHandleCreated && this.Visible) 
                                {
                                        Invalidate();
                                }
                        }
                }

                public Color StartColor 
                {
                        get 
                        {
                                return this.startColor;
                        }
                        set 
                        {
                                this.startColor = value;
                                // cause a repaint if necessary
                                if (this.IsHandleCreated && this.Visible) 
                                {
                                        Invalidate();
                                }
                        }
                }

                /// <summary>
                /// 角度を変更するためのプロパティ Angle を追加
                /// </summary>
                public float Angle 
                {
                        get 
                        {
                                return this.angle;
                        }
                        set 
                        {
                                this.angle = value;
                                // cause a repaint if necessary
                                if (this.IsHandleCreated && this.Visible) 
                                {
                                        Invalidate();
                                }
                        }
                }

                protected override void OnPaint(PaintEventArgs pe) 
                {
                        // paint the regular button background to get the 
                        // borders, etc.               
                        base.OnPaint(pe);
                        Graphics g = pe.Graphics;
                        Rectangle clientRect = this.ClientRectangle;
                        // MS のサンプルでは、-1, -1 だがそれでは不十分で -2, -2 にする必要がある。
                        clientRect.Inflate(-2,-2);
                        // create our gradient brush which will run from
                        // the top left to the bottom right.
                        Brush backgroundBrush = new LinearGradientBrush(
                                new Rectangle(clientRect.X,clientRect.Y, clientRect.Width, clientRect.Height),
                                startColor, 
                                endColor,
                                angle);      // 角度を追加
                        // fill the background with the gradient....
                        g.FillRectangle(backgroundBrush, clientRect);
                        // draw the text in the center of the client area.
                        g.DrawString(this.Text, 
                                this.Font, 
                                new SolidBrush(this.ForeColor), 
                                clientRect, 
                                format);
                }
        }
}

Form1.cs

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

namespace GradientButton
{
        /// <summary>
        /// Form1 の概要の説明です。
        /// </summary>
        public class Form1 : System.Windows.Forms.Form
        {
                private Uchukamen.Forms.GradientButton gradientButton1;
                private System.Windows.Forms.Timer timer1;
                private System.ComponentModel.IContainer components;

                public Form1()
                {
                        //
                        // Windows フォーム デザイナ サポートに必要です。
                        //
                        InitializeComponent();

                        //
                        // TODO: InitializeComponent 呼び出しの後に、コンストラクタ コードを追加してください。
                        //
                }

                /// <summary>
                /// 使用されているリソースに後処理を実行します。
                /// </summary>
                protected override void Dispose( bool disposing )
                {
                        if( disposing )
                        {
                                if (components != null) 
                                {
                                        components.Dispose();
                                }
                        }
                        base.Dispose( disposing );
                }

                #region Windows Form Designer generated code
                /// <summary>
                /// デザイナ サポートに必要なメソッドです。このメソッドの内容を
                /// コード エディタで変更しないでください。
                /// </summary>
                private void InitializeComponent()
                {
                        this.components = new System.ComponentModel.Container();
                        this.gradientButton1 = new Uchukamen.Forms.GradientButton();
                        this.timer1 = new System.Windows.Forms.Timer(this.components);
                        this.SuspendLayout();
                        // 
                        // gradientButton1
                        // 
                        this.gradientButton1.Angle = 0F;
                        this.gradientButton1.EndColor = System.Drawing.Color.Yellow;
                        this.gradientButton1.Location = new System.Drawing.Point(16, 16);
                        this.gradientButton1.Name = "gradientButton1";
                        this.gradientButton1.Size = new System.Drawing.Size(152, 64);
                        this.gradientButton1.StartColor = System.Drawing.Color.Magenta;
                        this.gradientButton1.TabIndex = 0;
                        this.gradientButton1.Text = "gradientButton1";
                        this.gradientButton1.Click += new System.EventHandler(this.OnClicked);
                        // 
                        // timer1
                        // 
                        this.timer1.Enabled = true;
                        this.timer1.Interval = 10;
                        this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
                        // 
                        // Form1
                        // 
                        this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
                        this.ClientSize = new System.Drawing.Size(264, 102);
                        this.Controls.AddRange(new System.Windows.Forms.Control[] {
                                                                                                                                                  this.gradientButton1});
                        this.Name = "Form1";
                        this.Text = "Gradient Button";
                        this.ResumeLayout(false);

                }
                #endregion

                /// <summary>
                /// アプリケーションのメイン エントリ ポイントです。
                /// </summary>
                [STAThread]
                static void Main() 
                {
                        Application.Run(new Form1());
                }

                private void OnClicked(object sender, System.EventArgs e)
                {
                
                }

                private void timer1_Tick(object sender, System.EventArgs e)
                {
                        this.gradientButton1.Angle += 10;
                        if ( this.gradientButton1.Angle > 360)
                                this.gradientButton1.Angle = 0;


                }
        }
}