我可以在按钮内绘制图形吗?

4
我一直在阅读stackoverflow以学习,现在我遇到了一个可以提问的情况。我正在制作一个类似Simon Says的记忆游戏,其中我向用户展示图形,用户必须按照相同的顺序点击按钮。我希望在用户点击的按钮内绘制我正在绘制在屏幕上的形状,因为将形状与形状进行比较比将形状与标有形状名称的按钮进行比较要容易得多。
希望我的问题很清楚,谢谢您的关注!

C# 对按钮一无所知。它是 WinForms、WPF、ASP.NET 还是其他应用程序? - zerkms
使用背景为按钮。 - Senad Meškin
@zerkms 抱歉,是WinForms。 - aperoll
5个回答

2
是的,您可以设置按钮的图像属性。或者,您可以绘制非矩形按钮,即任何形状的按钮。以下代码演示了这两种技术:
using System;
using System.Drawing;
using System.Windows.Forms;

class ShapeButton : Button {
  public Action<PaintEventArgs> DoPaint { get; set; }
  protected override void OnPaint(PaintEventArgs e) {
    if (DoPaint != null) { DoPaint(e); }
  }
}

static class Program {
  static void Main() {
    // Ellipse button
    ShapeButton ellipseButton = new ShapeButton();
    ellipseButton.Location = new Point(10, 10);
    ellipseButton.Size = new Size(80, 80);
    ellipseButton.DoPaint = delegate(PaintEventArgs e) {
      Graphics graphics = e.Graphics;
      SolidBrush brush1 = new SolidBrush(SystemColors.ButtonFace);
      graphics.FillRectangle(brush1, 0, 0, ellipseButton.Width, ellipseButton.Height);
      SolidBrush brush2 = new SolidBrush(Color.Red);
      graphics.FillEllipse(brush2, 0, 0, ellipseButton.Width, ellipseButton.Height);
    };
    ellipseButton.Click += delegate(object sender, EventArgs e) {
      MessageBox.Show("Ellipse!");
    };

    // Triangle button
    ShapeButton triangleButton = new ShapeButton();
    triangleButton.Location = new Point(100, 10);
    triangleButton.Size = new Size(80, 80);
    triangleButton.DoPaint = delegate(PaintEventArgs e) {
      Graphics graphics = e.Graphics;
      SolidBrush brush1 = new SolidBrush(SystemColors.ButtonFace);
      graphics.FillRectangle(brush1, 0, 0, triangleButton.Width, triangleButton.Height);
      SolidBrush brush2 = new SolidBrush(Color.Green);
      Point[] points = { 
        new Point(triangleButton.Width / 2, 0), 
        new Point(0, triangleButton.Height), 
        new Point(triangleButton.Width, triangleButton.Height) 
      };
      graphics.FillPolygon(brush2, points);
    };
    triangleButton.Click += delegate(object sender, EventArgs e) {
      MessageBox.Show("Triangle!");
    };

    // Star button (using image)
    Button starButton = new Button();
    starButton.Location = new Point(190, 10);
    starButton.Size = new Size(80, 80);
    starButton.Image = new Bitmap("Star.png");
    starButton.Click += delegate(object sender, EventArgs e) {
      MessageBox.Show("Star!");
    };

    // The form
    Form form = new Form();
    form.Text = "Shape Button Test";
    form.ClientSize = new Size(280, 100);
    form.Controls.Add(ellipseButton);
    form.Controls.Add(triangleButton);
    form.Controls.Add(starButton);
    form.ShowDialog();
  }
}

结果(点击三角形按钮后):

Shape Button Test form


1
为什么不使用PictureBox而不是Buttons。你只需要将任务添加到其事件/OnClick中即可。当然,你可以在运行时将任何图像加载到任何PictureBox中。

1
在WinForms中,要在运行时更改按钮的图像,您可以使用以下代码:
button1.Image = new Bitmap(Image.FromFile(@"Pictures\Koala.jpg"));

这应该添加到事件处理程序中。例如,如果你想在按钮被点击时显示图像,你需要订阅按钮的Click事件,并将代码添加到处理程序方法中:

private void button1_Click(object sender, EventArgs e)
{
    button1.Image = new Bitmap(Image.FromFile(@"Pictures\Koala.jpg"));
}

1
在我的示例中, 我有一个pictureBox用于展示,两个按钮,一个用于控制,一个用于绘制。
//odd display, even draw
int count = 0;
Image storePicture;

//whenever the background image changed,store it
private void pictureBoxShow_BackgroundImageChanged(object sender, EventArgs e)
{
    //you can stored to a Image array if you have series pictures to show
    storePicture = pictureBoxShow.BackgroundImage;
}

private void buttonControl_Click(object sender, EventArgs e)
{
    count++;
    //odd show picture, even draw picture on button
    if (count % 2 == 1)
        pictureBoxShow.BackgroundImage = new Bitmap("shapes.JPG");
    else
    { 
        //in case you want to clear text on the button
        buttonDrawn.Text = null;
        //recreate the picture so that it fit the button size
        buttonDrawn.Image = new Bitmap(storePicture, new Size(buttonDrawn.Width, buttonDrawn.Height));
    }
}

请记得将处理程序附加到相应的事件上。^^

0
上面的代码很棒,但是你可以在包含圆形的正方形外部点击并获取点击事件。 如果你想仅在用户在形状内部点击时捕获点击事件,你需要设置区域属性,类似于这样:
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        GraphicsPath gp = new GraphicsPath();
        gp.AddEllipse(0, 0, 100, 100);
        Button1.Region = new Region(gp);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接