Hello, I have to make a very basic paintlike program for school, and I've ran into a problem I have no clue how to solve. I hope one of you friendly forum-goers can help me out. Here's the problem:


I have a class called Figuur (shape in Dutch) and * inheriting classes called Lijn (line), Rechthoek (rectangle), Driehoek (triangle), Cirkel (circle) and Ellips (ellips).

Whenever I draw something (using graphicObj) on my designated panel, I create an object of the class of what I'm drawing (always one of the classes that inherit from Figuur) I store the object in myFiguurLijst (myShapeList) like so for example:

myFiguurLijst.AddFiguur(myCirkel);

I have an IEnumerable class of my own for FiguurLijst, which stores the objects it gets with AddFiguur in an array called fLijst (fList).

using System;
using System.Collections;
using System.Linq;
using System.Text;

namespace WindowsFormsApplication1
{
    public class FiguurLijst : IEnumerable
    {
        public int lengte
        {
            get
            {
                return fLijst.Count;
            }
        }
        
        ArrayList fLijst = new ArrayList();

        public IEnumerator GetEnumerator()
        {
            return (IEnumerator)this;
        }


        public void AddFiguur(object x)
        {
            fLijst.Add(x);
        }

        public object AskFiguur(int x)
        {
            return fLijst[x];
        }
    }
}

This is all working as far as I can tell, the problem I have is with creating persistent graphics as my teacher called it, or how to make all the things I've drawn refresh on panel at the press of a button or when you minimise the window.

I use foreach on every Figuur in myFiguurLijst, use case on the object's variable vorm (shape) and depending on which shape it is, I want to pass the object to the corresponding function. (paintLijn, paintRectangle, ...)

That's where I'm stuck. I'll show you the code. This is the foreach loop that determines which shape the current object is.

private void panel1_Paint(object sender, PaintEventArgs e)
        {
            foreach (Figuur o in myFiguurLijst)
            {
                switch (o.vorm)
                {
                    case "LIJN":
                        paintLijn(o);
                        break;
                    case "RECHTHOEK":
                        paintRechthoek(o);
                    case "DRIEHOEK":
                        paintDriehoek(o);
                        break;
                    case "CIRKEL":
                        paintCirkel(o);
                        break;
                    case "ELLIPS":
                        paintEllips(o);
                        break;
                }
            }

        }

And these are the paint functions I'm passing them to:

public void paintLijn(Lijn e)
        {
            System.Drawing.Graphics graphicsObj;
            graphicsObj = this.panel1.CreateGraphics();
            graphicsObj.DrawLine(myPen, e.x, e.y, e.x2, e.y2);
        }

        public void paintRechthoek(Rechthoek e)
        {
            System.Drawing.Graphics graphicsObj;
            graphicsObj = this.panel1.CreateGraphics();
            graphicsObj.DrawRectangle(myPen, e.x, e.y, e.breedte, e.hoogte);
        }
        
        public void paintDriehoek(Driehoek e)
        {
            System.Drawing.Graphics graphicsObj;
            graphicsObj = this.panel1.CreateGraphics();
            graphicsObj.DrawLine(myPen, e.x, e.y, e.x2, e.y2);
            graphicsObj.DrawLine(myPen, e.x2, e.y2, e.x3, e.y3);
            graphicsObj.DrawLine(myPen, e.x3, e.y3, e.x, e.y);
        }

        public void paintCirkel(Cirkel e)
        {
            System.Drawing.Graphics graphicsObj;
            graphicsObj = this.panel1.CreateGraphics();
            graphicsObj.DrawEllipse(myPen, e.x, e.y, e.breedte, e.hoogte);
        }

        public void paintEllips(Ellips e)
        {
            System.Drawing.Graphics graphicsObj;
            graphicsObj = this.panel1.CreateGraphics();
            graphicsObj.DrawEllipse(myPen, e.x, e.y, e.breedte, e.hoogte);
        }

The errors I get for all 5 of my shape-derived classes are:

The best overloaded method match for 'WindowsFormsApplication1.TekenApplicatie.paintLijn(WindowsFormsApplication1.Lijn)' has some invalid arguments

Argument '1': cannot convert from 'WindowsFormsApplication1.Figuur' to 'WindowsFormsApplication1.Lijn

I hope I've explained my problem properly and that you guys can help me out. :p

Thanks in advance,
Feanorith

What you need is double buffering. What happens is that each time you minimizer or drag something over your panel its automaticly repaint from the original state. What you have to do is, before designing it in your canvas, you need to save it a separate object that is not on the UI. After that, you need to ovveride repaint so it repaint from the buffered panel and not from the original state of the panel/canvas.

You need to cast the Figuur type object o to the actual class type of the parameter in your draw functions. E.G.

paintLijn((Lijn)o);

This is why you are getting the invalid arguments error.

I would also recommend passing the graphics object form the PaintEventArgs ( e.Graphics ) in to your draw methods. This will make them more general and re-useable and simplify your code a lot.

{
                   ...
                 case "LIJN":
                      paintLijn(e.Graphics, (Lijn)o);
                      break;
                  ...
        }

        public void paintLijn(System.Drawing.Graphics graphicsObj, Lijn e)
        {
            graphicsObj.DrawLine(myPen, e.x, e.y, e.x2, e.y2);
        }

Edited 6 Years Ago by nick.crane: n/a

Thanks a lot, nick.crane, that was exactly what I was looking for! Going to try it out right now. Also thanks for the hint, re-useability and simplicity is what we're supposed to aim for.
Thanks to you too, PierlucSS, but I found nick.crane's explanation to be is be easier to understand. ;)

This question has already been answered. Start a new discussion instead.