ITKeyword,专注技术干货聚合推荐

注册 | 登录

解决c# - Can I draw shapes within buttons?

itPublisher 分享于

2021腾讯云限时秒杀,爆款1核2G云服务器298元/3年!(领取2860元代金券),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1062

2021阿里云最低价产品入口+领取代金券(老用户3折起),
入口地址https://www.aliyun.com/minisite/goods

I've been reading stackoverflow for a while now just to learn, and I've come across a situation where I can finally ask a question. I'm making a Simon Says type memory game, where I flash shapes at the user, and the user has to click a button in the same order the shapes were shown to them. I want to draw the shape that I'm drawing on the screen within the button that they are clicking because it's much easier to remember and compare shapes to shapes rather than shapes to a button that says the shapes name.

Hopefully my question is clear, and thanks for taking a look!

c# winforms draw shapes
|
  this question
edited Mar 26 '14 at 0:24 V-SHY 1,893 3 14 30 asked Mar 25 '14 at 23:39 agnl 25 6      c# has no idea about buttons. Is it a winforms or wpf or asp.net or whatever else application? –  zerkms Mar 25 '14 at 23:40      Use background for buttons –  Senad Meškin Mar 25 '14 at 23:41      @zerkms sorry, winforms. –  agnl Mar 25 '14 at 23:48

 | 

5 Answers
5

解决方法

Yes, you can set the Image property of Button. Alternatively, you can draw non-rectangular buttons, that is, buttons of any shape. The following code demonstrates both techniques:

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();
  }
}

Result (after clicking on the triangle button):


|
  this answer
edited Mar 26 '14 at 0:42 answered Mar 25 '14 at 23:43 kol 15.7k 9 45 86      This is a perfect example, thanks a ton @kol! –  agnl Mar 26 '14 at 15:51      You're welcome :) –  kol Mar 26 '14 at 16:14

 | 

In winforms to change the button's image at runtime you can use something like this:

button1.Image = new Bitmap(Image.FromFile(@"Pictures\Koala.jpg"));

It should be added to event handler. For example if you want to show the image when the button is clicked you subscribe to Click event of the button and add the code into the handler method:

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

|
  this answer
answered Mar 26 '14 at 0:27 PiotrWolkowski 4,778 5 18 37

 | 

In my example,

I have a pictureBox to show, two buttons, one to control, one to be drawn.

//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));
    }
}

Please remember to attach the handlers to corresponding events. ^^


|
  this answer
edited Mar 26 '14 at 1:14 answered Mar 26 '14 at 0:39 V-SHY 1,893 3 14 30

 | 

Why not using PictureBox instead of Buttons. you have just to add your task to its event/OnClick Of course you can load any Image to any PictureBox in runtime


|
  this answer
answered Mar 26 '14 at 4:06 chouaib 2,404 5 13 29

 |  -1

The code above is great, however you can click outside the circle within a square containing the circle and get the click event. If you want to capture the click only if the user clicks inside the shape you have to set the region property with something like this

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);
    }
}

|
  this answer
answered Oct 9 '15 at 15:12 DGaleano 101 4

 | 


相关阅读排行


相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。