Reputation: 63
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?
Upvotes: 0
Views: 145
Reputation: 2111
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.
Upvotes: 3
Reputation: 1495
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.
Upvotes: 1
Reputation: 21
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.
Upvotes: 0