0

Hi guys I'm trying to make a "minipaint" application which has three buttons(rectangle, circle and line). I'm having problem with making my buttons work. For example I have this rectangle class which inherits color, thickness, startpoints x, y from shape:

class rectangle : shape
{
    public int length { get; set; }
    public int width { get; set; }

    public override void Draw(Graphics g)
    {
        g.DrawRectangle(new Pen(color), new Rectangle(startx, starty, width, length));
    }
}

Now I want my rectangle_btn_Click to print a rectangle in my panel whenever I click on it. here is my panel code:

private void panel1_Paint(object sender, PaintEventArgs e)
{
    Graphics g = panel1.CreateGraphics();
}

and this is my button:

private void rectangle_btn_Click(object sender, EventArgs e)
{
    rectangle r = new rectangle();
    int retval = r.Draw(g);
}

But it has an error and it does not recognize g. How should I make this work?

3 Answers 3

3

You need to declare your Graphics object globally:

private Graphics g; 

private void panel1_Paint(object sender, PaintEventArgs e)
{
    g = panel1.CreateGraphics();
}

Then this should also work

private void rectangle_btn_Click(object sender, EventArgs e)
{
    rectangle r = new rectangle();
    r.Draw(g);
}

This assumes panel1_Paint and rectangle_btn_Click are both declared in the same class.

EDIT:

As @krw12572 pointed out the problem with this is that after minimizing the form the drawn object will disappear because the panel will be redrawn. To solve the problem following edits need to be made:

private List<shape> shapes = new List<shape>(); 

private void panel1_Paint(object sender, PaintEventArgs e)
{
    foreach (var shape in shapes) {
       shape.Draw(e.Graphics);
    }
}

private void button1_Click(object sender, EventArgs e) 
{   
    //This will however draw a rectangle at a fixed position with a fixed size         
    rectangle r = new rectangle() {startx = 10, starty = 10, length = 10, width = 10, color = Color.Black};
    shapes.Add(r);
    panel1.Invalidate();
}

Also the classes should look something like this:

public class shape
{
    public Color color { get; set; }
    public int width { get; set; }
    public int startx { get; set; }
    public int starty { get; set; }

    public virtual void Draw(Graphics g)
    {

    }
}

public class rectangle : shape
{
    public int length { get; set; }
    public int width { get; set; }
    public override void Draw(Graphics g)
    {
        g.DrawRectangle(new Pen(color), new Rectangle(startx, starty, width, length));
    }
}

This approach uses a cache with all objects that need to be drawn. On button click a object is added to the cache.

Sign up to request clarification or add additional context in comments.

6 Comments

No dispose = bad.
This solution will fix syntax error and also draw rectangle but when panel1 is redrawn, that rectangle will disappear. Try minimizing and again maximizing application(after rectangle is drawn) to see what I'm talking about.
@krw12572 I update my answer considering your concerns. I also tested it out and it should work correctly even after minimizing and maximizing again.
Why do you need a global Graphics g;? You can use e.graphics from PaintEventArgs and call shape.Draw(e.Graphics).
You are right, there is no more need to have the Graphics global anymore. Tnx
|
1

You should perform any painting only in Paint event handler. Use graphics object from Paint event handler.

Implementing this way may be tricky but whenever your panel is redrawn, your painted shape will disappear if you don't perform painting in Paint event.

private shape _shape;

private void panel1_Paint(object sender, PaintEventArgs e)
{
    _shape.Draw(e.Graphics);
}

private void rectangle_btn_Click(object sender, EventArgs e)
{
    _shape = new rectangle();
    panel1.Invalidate();
}

Update: Above answer is assuming you have Draw(Graphics g) method in your base class shape and it's overridden/implemented in rectangle class.

2 Comments

it has "can't assign to Draw because it is a mehod group" error for the line _shape.Draw(e.Graphics);
That's because your Draw method is not written in shape class. Now, instead of private shape _shape; try private rectangle _shape;. That should work.
0

You should either declare your Graphics variable 'g' inside rectangle_btn_click or at the class level outside any methods scope. Then use it inside your stubs.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.