2013-07-13 178 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'的方法,我们不需要任何转换,代码对于不熟悉“转换”的人来说看起来更简单。 –