2

I'm very new to windows form coding and I'm trying to make a minipaint which has three buttons (circle,rectangle and line) and when it gets a button as an input , it will draw the shape in panel. I have this shape class

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

which has color,width and start position properties.then I have this rectangle class for example:

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

which inherits the share properties from the shape class. now I want to print a rectangle in panel . I'm familiar with DrawRectangle method and I printed a rectangle as bellow:

Pen black = new Pen(Color.Black);
Rectangle rect = new Rectangle(20,20,400,200);
private void panel1_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    g.DrawRectangle(black, rect);
}

but I don't know how to draw a rectangle from class rectangle:shape. I'm also having problem with assigning value from click button to rectangle. can you please help me?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
sara
  • 63
  • 9
  • You need to convert the MyRectangle to the generic Rectangle or just mash MyRectangle's values into an array of Points you calculate from your startx/y and it's lengths and use DrawPolygon. I would probably make a method in the MyRectangle.GetRectangle() that returns the System.Drawing.Rectangle – Poody Nov 08 '16 at 07:06
  • should I make a draw method in rectangle class? something like " void draw() { System.Drawing.Rectangle(startx,starty,length,width); }" but this doesn't work – sara Nov 08 '16 at 07:23
  • I believe that your definition of width in your shape class should most likely be thickness (so as not to get confused with width in your rectangle inherited class (and others). – Troy Mac1ure Nov 08 '16 at 07:25
  • Take a look at the `Circle` class in [this example](http://stackoverflow.com/a/38347945/3110834) or the `IShape` interface and implementations in [this other example](http://stackoverflow.com/a/38749134/3110834). – Reza Aghaei Nov 08 '16 at 10:29

2 Answers2

1

May I suggest you have one draw function in your base class that each shape overrides.

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

        public virtual void Draw(Graphics g)
        {
        }
    }

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

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

Then any shape can be drawn by calling .Draw(graphics). Define your rectangle:

        rectangle rectangle = new rectangle();
        rectangle.startx = 20;
        rectangle.starty = 20;
        rectangle.width = 400;
        rectangle.length = 200;

and then in your OnPaint (or wherever your are going to do it):

Graphics g = panel1.CreateGraphics();
rectangle.Draw(g);

The beauty of doing it this way is you can have a List and just iterate through them and draw each one once you have multiple shapes:

Graphics g = panel1.CreateGraphics();
foreach (shape s in shapes)          // Assuming shapes is List<shape>
    s.Draw(g);
Troy Mac1ure
  • 637
  • 4
  • 9
  • thank you so much for that. but how am I suppose to call this on my panel? – sara Nov 08 '16 at 07:39
  • Get the Graphics for your panel such as: Graphics g = panel1.CreateGraphics(); and then pass that to your shape draw function. After creating a rectangle named rect1 for example, you can then just call rect1.Draw(g); to draw it to your panel1 – Troy Mac1ure Nov 08 '16 at 07:43
  • it doesn't recognize rectangle.Draw(g) in panel1_paint :( – sara Nov 08 '16 at 08:11
  • You will have to declare your variable globally to access it anywhere within the class, not within a function. – Troy Mac1ure Nov 08 '16 at 08:57
  • 2
    @sara Do not use CreateGraphics. Use the panel's paint event where the Graphics are supplied in the `e` parameter. CreateGraphics is a temporary drawing, easily erased by minimizing and restoring the form, etc. – LarsTech Nov 08 '16 at 16:44
1

The following code allows you to drag and draw a Rectangle on a PictureBox. The conversion is implemented in MyRectangle. I also used slightly different properties.

public class Shape
{
    public Color color { get; set; }
    public Point origin { get; set; }
}

public class MyRectangle : Shape
{
    public Size size { get; set; }

    public Rectangle ToRectangle()
    {
        return new Rectangle(origin, size);
    }
}

public partial class Form1 : Form
{
    Point mouseDownPoint;

    public Form1()
    {
        InitializeComponent();
    }

    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        mouseDownPoint = e.Location;
    }

    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
        MyRectangle rect = new MyRectangle();
        rect.origin = mouseDownPoint;
        rect.size = Size.Subtract((Size)e.Location, (Size)mouseDownPoint);

        pictureBox1.CreateGraphics().DrawRectangle(new Pen(Brushes.Black), rect.ToRectangle());
    }
}

And maybe consider using PascalCase for class names. (Shape instead of shape)

sknt
  • 963
  • 6
  • 16