2013-07-13 210 views
0

如何在WinForms中製作這樣的按鈕?自定義按鈕

enter image description here

它總是這樣

enter image description here

+0

設置透明度顏色 – Sayse

+1

..不要畫出邊框和FontStyle.Bold文字..?你能告訴我們你的代碼嗎? –

+0

Sayce - 不工作:( –

回答

1

作爲一種變通方法(除去邊框)可以設置Button.FlatStyleFlat並設置Button.FlatAppearance.BorderSize0。您也可以修改FlatAppearance.MouseDownBackColor/MouseOverBackColor

-1

您可以在圖像按鈕

+0

是的。我相信你可以。 –

0

添加單擊事件,您可以通過影響.Region財產重繪按鈕的輪廓。這裏有一個我之前寫過的示例代碼(現在已經快速從VB.NET轉換),展示瞭如何創建一個橢圓形按鈕button2,以及一個複雜多邊形(X)button1。

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Drawing.Drawing2D; 

    namespace WindowsFormsApplication2 
    { 
     public partial class Form1 : Form 
     { 
      public Form1() 
      { 
       InitializeComponent(); 
      } 

      private void Form1_Load(object sender, EventArgs e) 
      { 
       GraphicsPath pathPolygon = new GraphicsPath(FillMode.Winding); 
       GraphicsPath pathEllipse = new GraphicsPath(FillMode.Winding); 


       //------ POLYGON (X) 
       Point[] points = new Point[12]; 
       points[0].X = 5; 
       points[0].Y = 15; 
       points[1].X = 10; 
       points[1].Y = 10; 
       points[2].X = 18; 
       points[2].Y = 18; 
       points[3].X = 26; 
       points[3].Y = 10; 
       points[4].X = 31; 
       points[4].Y = 15; 
       points[5].X = 23; 
       points[5].Y = 23; 
       points[6].X = 31; 
       points[6].Y = 31; 
       points[7].X = 26; 
       points[7].Y = 36; 
       points[8].X = 18; 
       points[8].Y = 28; 
       points[9].X = 10; 
       points[9].Y = 36; 
       points[10].X = 5; 
       points[10].Y = 31; 
       points[11].X = 13; 
       points[11].Y = 23; 

       Point maxVals = new Point(31, 36); 

       pathPolygon.AddPolygon(points); 

       Region region = new Region(pathPolygon); 

       button1.BackColor = Color.Red; 
       button1.FlatAppearance.BorderSize = 0; 
       button1.FlatStyle = FlatStyle.Flat; 
       button1.Region = region; 
       button1.SetBounds(button1.Location.X, button1.Location.Y, maxVals.X, maxVals.Y); 

       Rectangle ellipse = new Rectangle(0, 0, 100, 50); 
       maxVals = new Point(100, 50); 
       pathEllipse.AddEllipse(ellipse); 
       region = new Region(pathEllipse); 

       button2.BackColor = Color.Red; 
       button2.FlatAppearance.BorderSize = 0; 
       button2.FlatStyle = FlatStyle.Flat; 
       button2.Region = region; 
       button2.SetBounds(button2.Location.X, button2.Location.Y, maxVals.X, maxVals.Y); 

      } 
     } 
    } 

正如你所看到的,橢圓形的選擇是要簡單得多,而且更靈活(儘管它可能是你正在尋找最好的解決方案;請記住:你可以用寬度播放/高度在.SetBounds到「切割形狀」)。多邊形看起來有些複雜,但是一旦習慣了程序,就很簡單:提出繪製所需輪廓所需的所有點(例如,對於矩形,需要4個點,即4個頂點)並輸入它們在我提供的代碼中(不要忘記在maxVals中包含最大的X/Y值)。

4

我編寫這是不是一個完整的解決方案,但可以幫助你看到它的行動,並進一步去製作自己的按鈕:

public class RoundButton : Button 
{ 
    GraphicsPath borderPath; 
    protected override void OnSizeChanged(EventArgs e) 
    { 
     base.OnSizeChanged(e); 
     UpdateRegion(); 
    } 
    private void UpdateRegion() 
    { 
     borderPath = new GraphicsPath(); 
     borderPath.AddArc(new Rectangle(0, 0, Height, Height), 90, 180); 
     borderPath.AddLine(new Point(Height/2, 0), new Point(Width - Height/2, 0)); 
     borderPath.AddArc(new Rectangle(Width - Height, 0, Height, Height), -90, 180); 
     borderPath.AddLine(new Point(Width - Height/2, Height), new Point(Height/2, Height)); 
     Region = new Region(borderPath); 
    } 
    protected override void OnPaint(PaintEventArgs pevent) 
    { 
     pevent.Graphics.Clear(Color.Black);    
     Color cl1 = isMouseOver ? Color.FromArgb(100, Color.Yellow) : Color.FromArgb(100, Color.Aqua); 
     Color cl2 = isMouseOver ? Color.Yellow : Color.Aqua; 
     if (MouseButtons == MouseButtons.Left) cl2 = cl1; 
     using (LinearGradientBrush brush = new LinearGradientBrush(ClientRectangle, cl1, cl2, 90)) 
     { 
      pevent.Graphics.FillPath(brush, borderPath); 
      pevent.Graphics.ScaleTransform(0.8f, 0.4f);     
      pevent.Graphics.TranslateTransform(0.1f * ClientSize.Width, 0.1f * ClientSize.Height, MatrixOrder.Append); 
     } 
     if(!(MouseButtons == MouseButtons.Left)) 
      pevent.Graphics.FillPath(new SolidBrush(Color.FromArgb(100, Color.White)), borderPath); 
     pevent.Graphics.ResetTransform(); 

     pevent.Graphics.SmoothingMode = SmoothingMode.HighQuality; 
     float penSize = MouseButtons == MouseButtons.Left ? 4 : 2.5f; 
     using (Pen pen = new Pen(Color.Gray) { Width = penSize }) 
     { 
      pevent.Graphics.DrawPath(pen, borderPath); 
     } 
     using (StringFormat sf = new StringFormat { LineAlignment = StringAlignment.Center, Alignment = StringAlignment.Center }) 
     { 
      Rectangle rect = ClientRectangle; 
      if (MouseButtons == MouseButtons.Left) rect.Offset(-1, -1); 
      pevent.Graphics.DrawString(Text, Font, new SolidBrush(ForeColor), rect, sf); 
     } 
    } 
    bool isMouseOver;   
    protected override void OnMouseEnter(EventArgs e) 
    { 
     base.OnMouseEnter(e); 
     isMouseOver = true;    
    } 
    protected override void OnMouseLeave(EventArgs e) 
    { 
     base.OnMouseLeave(e); 
     isMouseOver = false;    
    }   
} 

下面是它的外觀:

enter image description here

如果您更換new LinearGradientBrush(...)中的cl1cl2,則按鈕看起來會與此類似:

enter image description here

+0

你的答案比我的更詳細,爲特定問題提供了一個更好的解決方案(我是第一個將它+1的人)。儘管如此,它可能太複雜了,不容易泛化,因此我會更好地讓我的讀者能夠尋找更通用的解決方案。 – varocarbas

+0

@varocarbas謝謝你,我的代碼並不是那麼複雜,它使用了最基本的概念,包括'Region,GraphicsPath,Graphics,LinearGradientBrush'和一個'Transform'。我使用'ScaleTransform'和'TranslateTransform'來將現有的'borderPath'轉換成較小的一個,這是一種懶惰,最好的解決方案是創建一個接收'Rectangle'並返回相應'borderPath'的方法,我們不需要任何轉換,代碼對於不熟悉「轉換」的人來說看起來更簡單。 –