简体   繁体   English

用鼠标单击C#绘制PictureBox中类中的图形

[英]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. 这是下面的form1。

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. 我将其重命名为Paintballs因为它包含许多内容,并且此名称更合适。 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. 您正在尝试在该类中实现Paint方法,但是它将Point作为参数并且不能在该类的任何实例状态上进行操作-这可能不是您想要的。 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. 在这里,我们有一个公共的Paint方法,该方法会将类中的所有彩弹绘制到传递给它的任何图形实例上。 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. 因此,我们通过将绘画方法推入paintballs类本身来简化了表单代码。 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. 这使类负责了解彩弹的外观,数量,位置以及如何将其绘制到Graphics对象。 This is step 1 in encapsulating responsibility. 这是封装职责的步骤1。

You're drawing from a list of points stored in that ballList variable. 您是从存储在该ballList变量中的点的列表中绘制的。 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 . 公开Paintball中的myClick列表,并在pictureBox1_Paint方法中遍历该列表而不是ballList

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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