創作內容

18 GP

C# 自定義Button

作者:貓貓風 ฅ●ω●ฅ│2019-02-01 14:20:06│巴幣:36│人氣:2996
.

















在WinForm中有很多元件可能現有可以變更的樣式很少,或是可能會完全無法變更

如果想要變更就需要重新繪製元件,並定義所需要的屬性

以本篇來說,一般的按鍵四邊都是偏稜角,本身也只有字型跟底色可以選擇

如果要讓按鍵看起來更華麗,則需要重繪

以下為重繪按鍵實作範例

定義 AquaButton 類別 繼承 Button 進行重繪

相關連結




  1. using System;  
  2. using System.Windows.Forms;  
  3. using System.Drawing;  
  4. using System.Drawing.Drawing2D;  
  5. using System.Diagnostics;  
  6. using System.Drawing.Imaging;  
  7. using System.ComponentModel;  
  8.   
  9. namespace AquaButtonTester  
  10. {  
  11.     /// <summary>  
  12.     /// Summary description for AquaButton.  
  13.     /// </summary>  
  14.     [Serializable]  
  15.     public class AquaButton : System.Windows.Forms.Button  
  16.     {  
  17.         /// <summary>   
  18.         /// Required designer variable.  
  19.         /// </summary>  
  20.         private System.ComponentModel.Container components = null;  
  21.         private bool pulseOnFocus;  
  22.   
  23.         ///  
  24.         ///Additional variables to handle pulsing  
  25.         ///  
  26.         private ImageAttributes imgAttr = new ImageAttributes();  
  27.         private float gamma;  
  28.         private float minGamma;  
  29.         private float maxGamma;  
  30.         private float gammaStep;  
  31.         private Timer pulseTimer = new Timer();  
  32.         private Bitmap buttonBitmap;  
  33.         private Rectangle buttonBitmapRectangle;  
  34.   
  35.         public AquaButton()  
  36.         {  
  37.             // This call is required by the Windows.Forms Form Designer.  
  38.             InitializeComponent();  
  39.   
  40.             mouseAction = MouseActionType.None;  
  41.   
  42.             this.SetStyle(ControlStyles.AllPaintingInWmPaint |   
  43.                 ControlStyles.DoubleBuffer |   
  44.                 ControlStyles.UserPaint, true);  
  45.   
  46.             //The following defaults are better suited to draw the text outline  
  47.             this.Font = new Font("Arial Black", 12, FontStyle.Bold);  
  48.             this.BackColor = Color.DarkTurquoise;  
  49.             this.Size = new Size(112, 48);  
  50.   
  51.             //Initialize variables to Pulse button  
  52.             gamma = 1.0f;  
  53.             minGamma = 1.0f;  
  54.             maxGamma = 2.2f;  
  55.             gammaStep = .2f;  
  56.             pulseTimer.Interval = 90;  
  57.             pulseTimer.Tick +=new EventHandler(pulseTimer_Tick);  
  58.         }  
  59.   
  60.         [DefaultValue(false)]  
  61.         public bool PulseOnFocus   
  62.         {  
  63.             get { return pulseOnFocus; }  
  64.             set { pulseOnFocus = value; Invalidate(); }  
  65.         }  
  66.   
  67.   
  68.         /// <summary>   
  69.         /// Clean up any resources being used.  
  70.         /// </summary>  
  71.         protected override void Dispose( bool disposing )  
  72.         {  
  73.             if( disposing )  
  74.             {  
  75.                 if(components != null)  
  76.                 {  
  77.                     components.Dispose();  
  78.                 }  
  79.             }  
  80.             base.Dispose( disposing );  
  81.         }  
  82.         #region Component Designer generated code  
  83.         /// <summary>   
  84.         /// Required method for Designer support - do not modify   
  85.         /// the contents of this method with the code editor.  
  86.         /// </summary>  
  87.         private void InitializeComponent()  
  88.         {  
  89.             components = new System.ComponentModel.Container();  
  90.         }  
  91.         #endregion  
  92.   
  93.         private enum MouseActionType  
  94.         {  
  95.             None,  
  96.             Hover,  
  97.             Click  
  98.         }  
  99.   
  100.         private MouseActionType mouseAction;  
  101.   
  102.         protected override void OnPaint(PaintEventArgs e)  
  103.         {  
  104.             Graphics g = e.Graphics;  
  105.             g.Clear(Color.White);  
  106.             Color clr = this.BackColor;  
  107.             int shadowOffset = 8;  
  108.             int btnOffset = 0;  
  109.             switch (mouseAction)  
  110.             {  
  111.                 case MouseActionType.Click:  
  112.                     shadowOffset = 4;  
  113.                     clr = Color.Gold;  
  114.                     btnOffset = 2;  
  115.                     break;  
  116.                 case MouseActionType.Hover:  
  117.                     clr = Color.Gold;  
  118.                     break;  
  119.             }  
  120.             g.SmoothingMode = SmoothingMode.AntiAlias;  
  121.   
  122.             ///  
  123.             /// Create main colored shape  
  124.             ///   
  125.             Rectangle rc = new Rectangle(btnOffset,btnOffset,this.ClientSize.Width-8-
  126.              btnOffset, this.ClientSize.Height-8-btnOffset);  
  127.             GraphicsPath path1 = this.GetPath(rc, 20);  
  128.             LinearGradientBrush br1 = new LinearGradientBrush(new Point(0, 0),new
  129.             Point(0, rc.Height+6), clr, Color.White);  
  130.   
  131.             ///  
  132.             /// Create shadow  
  133.             ///   
  134.             Rectangle rc2 = rc;  
  135.             rc2.Offset(shadowOffset, shadowOffset);  
  136.             GraphicsPath path2 = this.GetPath(rc2, 20);  
  137.             PathGradientBrush br2 = new PathGradientBrush(path2);  
  138.             br2.CenterColor = ControlPaint.DarkDark(Color.Silver);  
  139.             br2.SurroundColors = new Color[]{Color.White};  
  140.   
  141.             ///  
  142.             /// Create top water color to give "aqua" effect  
  143.             ///   
  144.             Rectangle rc3 = rc;  
  145.             rc3.Inflate(-5, -5);  
  146.             rc3.Height = 15;  
  147.             GraphicsPath path3 = GetPath(rc3, 20);  
  148.             LinearGradientBrush br3 = new LinearGradientBrush(rc3, Color.FromArgb(255,
  149.             Color.White), Color.FromArgb(0, Color.White), LinearGradientMode.Vertical);  
  150.   
  151.             ///  
  152.             ///draw shapes  
  153.             ///  
  154.             g.FillPath(br2, path2); //draw shadow  
  155.             g.FillPath(br1, path1); //draw main  
  156.             g.FillPath(br3, path3); //draw top bubble  
  157.   
  158.             ///  
  159.             ///Create a backup of the button image to a bitmap so we can manipulate it's
  160.              pulsing action  
  161.             ///  
  162.             buttonBitmapRectangle = new Rectangle(rc.Location, rc.Size);  
  163.             buttonBitmap = new Bitmap(buttonBitmapRectangle.Width,
  164.             buttonBitmapRectangle.Height);  
  165.             Graphics g_bmp = Graphics.FromImage(buttonBitmap);  
  166.             g_bmp.SmoothingMode = SmoothingMode.AntiAlias;  
  167.             g_bmp.FillPath(br1, path1);  
  168.             g_bmp.FillPath(br3, path3);  
  169.   
  170.             ///  
  171.             ///Set the region for the button  
  172.             Region rgn = new Region(path1);  
  173.             rgn.Union(path2);  
  174.             this.Region = rgn;  
  175.   
  176.             ///  
  177.             /// Create a Path to draw the text to give the button a nice outline  
  178.             ///   
  179.             GraphicsPath path4 = new GraphicsPath();  
  180.               
  181.             RectangleF path1bounds = path1.GetBounds();  
  182.             Rectangle rcText = new Rectangle((int)path1bounds.X, (int)path1bounds.Y,
  183.             (int)path1bounds.Width, (int)path1bounds.Height);  
  184.   
  185.             StringFormat strformat = new StringFormat();  
  186.             strformat.Alignment = StringAlignment.Center;  
  187.             strformat.LineAlignment = StringAlignment.Center;  
  188.             path4.AddString(this.Text, this.Font.FontFamily, (int)this.Font.Style,
  189.             this.Font.Size, rcText, strformat);  
  190.   
  191.             Pen txtPen = new Pen(this.ForeColor, 1);  
  192.             g.DrawPath(txtPen, path4);  
  193.             g_bmp.DrawPath(txtPen, path4);  
  194.         }  
  195.         private GraphicsPath GetPath(Rectangle rc, int r)  
  196.         {  
  197.             int x = rc.X, y = rc.Y, w = rc.Width, h = rc.Height;  
  198.             GraphicsPath path = new GraphicsPath();  
  199.             path.AddArc(x, y, r, r, 180, 90);               //Upper left corner  
  200.             path.AddArc(x+w - r, y, r, r, 270, 90);         //Upper right corner  
  201.             path.AddArc(x+w - r, y+h - r, r, r, 0, 90);     //Lower right corner  
  202.             path.AddArc(x, y+h - r, r, r, 90, 90);          //Lower left corner  
  203.             path.CloseFigure();  
  204.             return path;  
  205.         }  
  206.   
  207.         protected override void OnMouseDown(MouseEventArgs e)  
  208.         {  
  209.             if (e.Button == MouseButtons.Left)  
  210.             {  
  211.                 this.mouseAction = MouseActionType.Click;  
  212.                 this.Invalidate();  
  213.             }  
  214.             base.OnMouseDown (e);  
  215.         }  
  216.   
  217.         protected override void OnMouseUp(MouseEventArgs e)  
  218.         {  
  219.             if (this.Bounds.Contains(e.X, e.Y))  
  220.                 this.mouseAction = MouseActionType.Hover;  
  221.             else  
  222.                 this.mouseAction = MouseActionType.None;  
  223.             this.Invalidate();  
  224.             base.OnMouseUp (e);  
  225.         }  
  226.   
  227.   
  228.         protected override void OnMouseEnter(EventArgs e)  
  229.         {  
  230.             this.mouseAction = MouseActionType.Hover;  
  231.             this.Invalidate();  
  232.             base.OnMouseEnter (e);  
  233.         }  
  234.   
  235.         protected override void OnMouseLeave(EventArgs e)  
  236.         {  
  237.             this.mouseAction = MouseActionType.None;  
  238.             this.Invalidate();  
  239.             base.OnMouseLeave (e);  
  240.         }  
  241.   
  242.         //-----------------------------------------------------------------  
  243.         // METHODS TO HANDLE PULSING  
  244.         //-----------------------------------------------------------------  
  245.   
  246.         protected override void OnGotFocus(EventArgs e)  
  247.         {  
  248.             base.OnGotFocus (e);  
  249.             if (this.pulseOnFocus)  
  250.                 pulseTimer.Start();  
  251.         }  
  252.   
  253.         protected override void OnLostFocus(EventArgs e)  
  254.         {  
  255.             base.OnLostFocus (e);  
  256.             pulseTimer.Stop();  
  257.             this.Invalidate();  //redraw to get back it's original picture  
  258.         }  
  259.   
  260.         private void pulseTimer_Tick(object sender, EventArgs e)  
  261.         {  
  262.             if (this.Focused && pulseOnFocus && buttonBitmap != null)  
  263.             {  
  264.                 gamma += gammaStep;  
  265.                 if (gamma > this.maxGamma) gammaStep = - gammaStep;  
  266.                 if (gamma < this.minGamma) gammaStep = Math.Abs(gammaStep);  
  267.                 imgAttr.SetGamma(gamma);       
  268.                 this.CreateGraphics().DrawImage(buttonBitmap,
  269.                 buttonBitmapRectangle, 0, 0,   
  270.                 buttonBitmap.Width, buttonBitmap.Height, GraphicsUnit.Pixel, imgAttr);  
  271.             }  
  272.         }  
  273.     }  
  274. }  


接著主程式直接使用定義好的按鍵

宣告定義的按鍵型別並使用


  1. using System;  
  2. using System.Drawing;  
  3. using System.Collections;  
  4. using System.ComponentModel;  
  5. using System.Windows.Forms;  
  6. using System.Data;  
  7.   
  8. namespace AquaButtonTester  
  9. {  
  10.     /// <summary>  
  11.     /// Summary description for Form1.  
  12.     /// </summary>  
  13.     public class Form1 : System.Windows.Forms.Form  
  14.     {  
  15.         private AquaButtonTester.AquaButton aquaButton1;  
  16.         private AquaButtonTester.AquaButton aquaButton2;  
  17.         private AquaButtonTester.AquaButton aquaButton3;  
  18.         private AquaButtonTester.AquaButton aquaButton4;  
  19.         private AquaButtonTester.AquaButton aquaButton5;  
  20.         private AquaButtonTester.AquaButton aquaButton6;  
  21.         /// <summary>  
  22.         /// Required designer variable.  
  23.         /// </summary>  
  24.         private System.ComponentModel.Container components = null;  
  25.   
  26.         public Form1()  
  27.         {  
  28.             //  
  29.             // Required for Windows Form Designer support  
  30.             //  
  31.             InitializeComponent();  
  32.   
  33.             //  
  34.             // TODO: Add any constructor code after InitializeComponent call  
  35.             //  
  36.         }  
  37.   
  38.         /// <summary>  
  39.         /// Clean up any resources being used.  
  40.         /// </summary>  
  41.         protected override void Dispose( bool disposing )  
  42.         {  
  43.             if( disposing )  
  44.             {  
  45.                 if (components != null)   
  46.                 {  
  47.                     components.Dispose();  
  48.                 }  
  49.             }  
  50.             base.Dispose( disposing );  
  51.         }  
  52.         #region Windows Form Designer generated code  
  53.         /// <summary>  
  54.         /// Required method for Designer support - do not modify  
  55.         /// the contents of this method with the code editor.  
  56.         /// </summary>  
  57.         private void InitializeComponent()  
  58.         {  
  59.             this.aquaButton1 = new AquaButtonTester.AquaButton();  
  60.             this.aquaButton2 = new AquaButtonTester.AquaButton();  
  61.             this.aquaButton3 = new AquaButtonTester.AquaButton();  
  62.             this.aquaButton4 = new AquaButtonTester.AquaButton();  
  63.             this.aquaButton5 = new AquaButtonTester.AquaButton();  
  64.             this.aquaButton6 = new AquaButtonTester.AquaButton();  
  65.             this.SuspendLayout();  
  66.             //   
  67.             // aquaButton1  
  68.             //   
  69.             this.aquaButton1.BackColor = System.Drawing.Color.DarkTurquoise;  
  70.             this.aquaButton1.Font = new System.Drawing.Font("Arial Black", 12F,
  71.             System.Drawing.FontStyle.Bold);  
  72.             this.aquaButton1.Location = new System.Drawing.Point(19, 22);  
  73.             this.aquaButton1.Name = "aquaButton1";  
  74.             this.aquaButton1.PulseOnFocus = true;  
  75.             this.aquaButton1.Size = new System.Drawing.Size(135, 67);  
  76.             this.aquaButton1.TabIndex = 0;  
  77.             this.aquaButton1.Text = "Button 1";  
  78.             this.aquaButton1.UseVisualStyleBackColor = false;  
  79.             this.aquaButton1.Click += new System.EventHandler(this.aquaButton_Click);  
  80.             //   
  81.             // aquaButton2  
  82.             //   
  83.             this.aquaButton2.BackColor = System.Drawing.Color.Tomato;  
  84.             this.aquaButton2.Font = new System.Drawing.Font("Arial Black", 12F,
  85.            System.Drawing.FontStyle.Bold);  
  86.             this.aquaButton2.Location = new System.Drawing.Point(182, 22);  
  87.             this.aquaButton2.Name = "aquaButton2";  
  88.             this.aquaButton2.Size = new System.Drawing.Size(135, 67);  
  89.             this.aquaButton2.TabIndex = 1;  
  90.             this.aquaButton2.Text = "Button 2";  
  91.             this.aquaButton2.UseVisualStyleBackColor = false;  
  92.             this.aquaButton2.Click += new System.EventHandler(this.aquaButton_Click);  
  93.             //   
  94.             // aquaButton3  
  95.             //   
  96.             this.aquaButton3.BackColor = System.Drawing.Color.RosyBrown;  
  97.             this.aquaButton3.Font = new System.Drawing.Font("Arial Black", 12F,
  98.             System.Drawing.FontStyle.Bold);  
  99.             this.aquaButton3.Location = new System.Drawing.Point(19, 100);  
  100.             this.aquaButton3.Name = "aquaButton3";  
  101.             this.aquaButton3.PulseOnFocus = true;  
  102.             this.aquaButton3.Size = new System.Drawing.Size(135, 66);  
  103.             this.aquaButton3.TabIndex = 3;  
  104.             this.aquaButton3.Text = "Button 3";  
  105.             this.aquaButton3.UseVisualStyleBackColor = false;  
  106.             this.aquaButton3.Click += new System.EventHandler(this.aquaButton_Click);  
  107.             //   
  108.             // aquaButton4  
  109.             //   
  110.             this.aquaButton4.BackColor = System.Drawing.Color.DodgerBlue;  
  111.             this.aquaButton4.Font = new System.Drawing.Font("Arial Black", 12F,
  112.             System.Drawing.FontStyle.Bold);  
  113.             this.aquaButton4.Location = new System.Drawing.Point(182, 100);  
  114.             this.aquaButton4.Name = "aquaButton4";  
  115.             this.aquaButton4.Size = new System.Drawing.Size(135, 66);  
  116.             this.aquaButton4.TabIndex = 2;  
  117.             this.aquaButton4.Text = "Button 4";  
  118.             this.aquaButton4.UseVisualStyleBackColor = false;  
  119.             this.aquaButton4.Click += new System.EventHandler(this.aquaButton_Click);  
  120.             //   
  121.             // aquaButton5  
  122.             //   
  123.             this.aquaButton5.BackColor = System.Drawing.Color.MediumSeaGreen;  
  124.             this.aquaButton5.Font = new System.Drawing.Font("Arial Black", 12F,
  125.             System.Drawing.FontStyle.Bold);  
  126.             this.aquaButton5.Location = new System.Drawing.Point(19, 188);  
  127.             this.aquaButton5.Name = "aquaButton5";  
  128.             this.aquaButton5.PulseOnFocus = true;  
  129.             this.aquaButton5.Size = new System.Drawing.Size(135, 67);  
  130.             this.aquaButton5.TabIndex = 1;  
  131.             this.aquaButton5.Text = "Button 5";  
  132.             this.aquaButton5.UseVisualStyleBackColor = false;  
  133.             this.aquaButton5.Click += new System.EventHandler(this.aquaButton_Click);  
  134.             //   
  135.             // aquaButton6  
  136.             //   
  137.             this.aquaButton6.BackColor = System.Drawing.Color.Violet;  
  138.             this.aquaButton6.Font = new System.Drawing.Font("Arial Black", 12F,
  139.             System.Drawing.FontStyle.Bold);  
  140.             this.aquaButton6.Location = new System.Drawing.Point(182, 188);  
  141.             this.aquaButton6.Name = "aquaButton6";  
  142.             this.aquaButton6.Size = new System.Drawing.Size(135, 67);  
  143.             this.aquaButton6.TabIndex = 0;  
  144.             this.aquaButton6.Text = "Button 6";  
  145.             this.aquaButton6.UseVisualStyleBackColor = false;  
  146.             this.aquaButton6.Click += new System.EventHandler(this.aquaButton_Click);  
  147.             //   
  148.             // Form1  
  149.             //   
  150.             this.AcceptButton = this.aquaButton2;  
  151.             this.AutoScaleBaseSize = new System.Drawing.Size(6, 18);  
  152.             this.BackColor = System.Drawing.Color.White;  
  153.             this.ClientSize = new System.Drawing.Size(433, 316);  
  154.             this.Controls.Add(this.aquaButton6);  
  155.             this.Controls.Add(this.aquaButton5);  
  156.             this.Controls.Add(this.aquaButton4);  
  157.             this.Controls.Add(this.aquaButton3);  
  158.             this.Controls.Add(this.aquaButton2);  
  159.             this.Controls.Add(this.aquaButton1);  
  160.             this.Name = "Form1";  
  161.             this.Text = "AquaButton Demo";  
  162.             this.Load += new System.EventHandler(this.Form1_Load);  
  163.             this.ResumeLayout(false);  
  164.   
  165.         }  
  166.         #endregion  
  167.   
  168.         /// <summary>  
  169.         /// The main entry point for the application.  
  170.         /// </summary>  
  171.         [STAThread]  
  172.         static void Main()   
  173.         {  
  174.             Application.Run(new Form1());  
  175.         }  
  176.   
  177.         private void aquaButton_Click(object sender, System.EventArgs e)  
  178.         {  
  179.             Button btn = (Button) sender;  
  180.             MessageBox.Show("You clicked " + btn.Name);  
  181.         }  
  182.   
  183.         private void Form1_Load(object sender, System.EventArgs e)  
  184.         {  
  185.             this.aquaButton1.Focus();  
  186.         }  
  187.     }  
  188. }  

執行結果

載入時每個按鍵呈現定義好的顏色與樣式


當選取 button1時,呈現黃底色



按下觸發事件



選取 button2時呈現黃底色



按下觸發事件



選取 button3時呈現黃底色


功能依此類推

可以依據想要的顏色與樣式對程式碼進行變更


引用網址:https://home.gamer.com.tw/TrackBack.php?sn=4279773
All rights reserved. 版權所有,保留一切權利

相關創作

同標籤作品搜尋:涼涼風|C#

留言共 8 篇留言

宇宙吃貨胖宅貓
推推喵

02-01 14:22

貓貓風 ฅ●ω●ฅ
桑Q O ω O02-01 14:22
小魚
加油, 新年快樂!

02-01 15:32

貓貓風 ฅ●ω●ฅ
[e12]02-01 16:11
Vin
貓貓風好厲害(ノ*>∀<)ノ♡,整理辛苦了,GP 奉上

02-01 16:22

貓貓風 ฅ●ω●ฅ
謝謝 Vin ^ ω ^02-01 16:28
南宮佟羽

02-01 18:18

貓貓風 ฅ●ω●ฅ
[e24]02-01 19:59
帥氣跳蚤蛋
剛學C#的介面,不過我在學WPF,之後該回頭補WIN FORM嗎??感覺這滿舊了~但還是有好多公司還再用~

02-02 10:13

貓貓風 ฅ●ω●ฅ
C# 到現在都還算業界主流02-02 23:42
小刀
好厲害!

02-02 15:05

貓貓風 ฅ●ω●ฅ
謝謝刀姊02-02 23:42
小魚
To 帥氣跳蚤蛋:
WinForm 跟 WPF 特色不一樣吧,
只是WinForm在美工上的變化沒辦法像WPF那麼自由,
但是以開發速度而言,
WinForm是比較方便不用花時間去寫介面,
當然可能因為我沒有去用Blend吧,
還是比較喜歡用原生的.

02-02 23:57

豬血糕愛好者
比較好奇怎不丟到Github

02-03 09:25

貓貓風 ฅ●ω●ฅ
不習慣用那個02-03 11:23
我要留言提醒:您尚未登入,請先登入再留言

18喜歡★s1234567 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:C# Modbus AS... 後一篇:C# Random Co...

追蹤私訊切換新版閱覽

作品資料夾

d88931122所有巴友
歡迎諸君來參觀老僧的小屋,內含Steam與Google Play遊戲、3D角色模組、Line貼圖看更多我要大聲說昨天20:54


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】