Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing on a panel by clicking a button in WinForms

I'm trying to make a program to draw on the a Panel (a square, circle, etc...) by clicking on a button.

I have not done much so far, just tried the code drawing directly to the panel but don't know how to move it to the button. Here is the code I have so far.

If you know a better method to draw than the one I'm using please let me know.

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

    private void mainPanel_Paint(object sender, PaintEventArgs e)
    {
        Graphics g;
        g = CreateGraphics();
        Pen pen = new Pen(Color.Black);
        Rectangle r = new Rectangle(10, 10, 100, 100);
        g.DrawRectangle(pen, r);
    }

    private void circleButton_Click(object sender, EventArgs e)
    {
    }

    private void drawButton_Click(object sender, EventArgs e)
    {
    }
}

}

like image 644
Tarek Alabbar Avatar asked Sep 01 '25 17:09

Tarek Alabbar


1 Answers

Using this extremely simplified example class..:

class DrawAction
{
    public char type { get; set; }
    public Rectangle rect { get; set; }
    public Color color { get; set; }
    //.....

    public DrawAction(char type_, Rectangle rect_, Color color_)
    { type = type_; rect = rect_; color = color_; }
}

Have a class level List<T>:

List<DrawAction> actions = new List<DrawAction>();

you would code a few buttons like this:

  private void RectangleButton_Click(object sender, EventArgs e)
{
    actions.Add(new DrawAction('R', new Rectangle(11, 22, 66, 88), Color.DarkGoldenrod));
    mainPanel.Invalidate();  // this triggers the Paint event!
}


private void circleButton_Click(object sender, EventArgs e)
{
    actions.Add(new DrawAction('E', new Rectangle(33, 44, 66, 88), Color.DarkGoldenrod));
    mainPanel.Invalidate();  // this triggers the Paint event!
}

And in the Paint event:

private void mainPanel_Paint(object sender, PaintEventArgs e)
{
    foreach (DrawAction da in actions)
    {
        if (da.type == 'R') e.Graphics.DrawRectangle(new Pen(da.color), da.rect);
        else if (da.type == 'E') e.Graphics.DrawEllipse(new Pen(da.color), da.rect);
        //..
    }
}

Also use a double-buffered Panel subclass:

class DrawPanel : Panel
{ 
    public DrawPanel() 
    { this.DoubleBuffered = true; BackColor = Color.Transparent; }
}

The next steps will be to add more types, like lines, curve, text; also colors, pen widths and styles. Also make it dynamic, so that you pick a tool and then click at the Panel..

For freehand drawing you need to collect a List<Point> in the MouseMove etc..

Lots of work, lots of fun.

Updates from comments:

Note: This is, as I wrote extremely simplified. I have character to draw shapes like Rectangle and Ellipse. With a little more code you can add more characters for a filled rectangle and a filledEllipse. But a) the shapes really ought to be in an Enum and b) more complicated shapes like lines, polygons, text, or shapes with rotation will need more data that just a Rectangle. .

The restriction to rectangle coodinates was a simplification, not so much of the shape but of the data structure. Your other shapes could be reduced to fit in a rectangle (four triangles and two hexagons come to mind); just add charcters and new drawxxx calls.. But evetually adding a List for complex shapes and maybe a string and a font will allow for more complex results..

like image 155
TaW Avatar answered Sep 04 '25 08:09

TaW