简体   繁体   中英

C# paint graphics from class in picturebox with mouse click

I want to paint a graphics object from a method (paint) I created in a separate class (Paintball). I want it to paint in a picturebox only when I left-click with my mouse and I want the point where I shoot to be stored in a List. When I try the code below, it doesn't shoot. Below is the class Paintball.

{
    private List<Point> myClick;

    public Paintball()
    {                 
        myClick = new List<Point>();
    }

    public void add(Point location)
    {
        myClick.Add(location);                    
    }

    public void paint(Graphics g, Point point)
    {
        g.FillEllipse(Brushes.Blue, point.X, point.Y, 20, 20);
    }
}

}

This is form1 below.

namespace AmazingPaintball
{
    public partial class Form1 : Form
    {
        Random positionX = new Random();
        Random positionY = new Random();
        Target einstein;
        int count;
        List<Point> ballList = new List<Point>();
        Paintball gun; 

        public Form1()
        {
            InitializeComponent();
            Point point = new Point(positionX.Next(0, 638), positionY.Next(0, 404));
            einstein = new Target(point);
            ptrEinstein.Location = point;
            gun = new Paintball();               
        }       

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            ptrEinstein.Location = einstein.Move(e.KeyData);
            pictureBox1.Update();
            pictureBox1.Refresh();           
        }




        private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
        {
            count++;
            gun.add(e.Location);
            pictureBox1.Refresh();


        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            foreach (var Paintball in ballList)
            {
                gun.paint(e.Graphics, this.PointToClient(Cursor.Position));
                pictureBox1.Refresh();               
            }                        
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            timer1.Start();
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            pictureBox1.Refresh();
        }       
    }
}

Please let me know if you know what has to be edited/created. Thank You

Your original code has many mistakes. Let's try to simplify what you are doing and tackle simply storing a list of points and drawing them to the picturebox.

public partial class Form1 : Form
{        
    List<Point> ballList = new List<Point>();        

    public Form1()
    {
        InitializeComponent();
    }

    private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
    {           
        ballList.Add(e.Location);
        pictureBox1.Refresh();
    }

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        foreach (Point pBall in ballList)
        {
            e.Graphics.FillEllipse(Brushes.Blue, pBall.X, pBall.Y, 20, 20);
        }
    }
}

Here we have a list, we add the click points to it in the click handler and paint them in the paint handler. Once you get comfortable with this, perhaps move to the next task in your program and ask a new question if you get stuck with the next feature.


Ok, I've got a bit of time, so let's look at your paintball class. I've renamed it Paintballs since it contains many of them and this name is more appropriate. If you want to keep the list of points private that's ok. You are trying to implement a Paint method in the class, but it takes a Point as argument and does not operate on any of the class's instance state - this probably isn't what you want. Consider now :

public class Paintballs
{
    private List<Point> myClick;

    public Paintballs()
    {
        myClick = new List<Point>();
    }

    public void Add(Point location)
    {
        myClick.Add(location);
    }

    public void Paint(Graphics g)
    {
        foreach (Point p in myClick)
        {
            g.FillEllipse(Brushes.Blue, p.X, p.Y, 20, 20);
        }
    }
}

Here we have a public Paint method that will draw all of the paintballs in the class to any graphics instance you pass to it. Now your form code would look like :

public partial class Form1 : Form
{
    Paintballs pBalls = new Paintballs();

    public Form1()
    {
        InitializeComponent();
    }

    private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
    {
        pBalls.Add(e.Location);
        pictureBox1.Refresh();
    }

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        pBalls.Paint(e.Graphics);
    }
}

So we've simplified the form code by pushing the painting method into the paintballs class itself. This makes the class responsible for knowing what the paintballs look like, how many there are, where they are, and how to draw them to a Graphics object. This is step 1 in encapsulating responsibility.

You're drawing from a list of points stored in that ballList variable. However, you've never added any points to that list.

Make the myClick list in Paintball public and, in the pictureBox1_Paint method, iterate through that list instead of ballList .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM