Draw a line using buttons as a coordinates on a PictureBox

北慕城南 提交于 2019-12-11 10:07:07

问题


Currently I am making a searching program for Rooms/Office based on the image shown.

I am having trouble on the program that I want show a line on the 2D map where buttons will be use to connect each coordinates of the line. But after searching a room no lines that will appear.

private void button2_Click(object sender, EventArgs e)
    {
        System.Drawing.Pen myPen;
        myPen = new System.Drawing.Pen(System.Drawing.Color.Red, 5);
        System.Drawing.Graphics frmGraphics = pictureBox1.CreateGraphics();

        if (textBox1.Text == "")
        {
            MessageBox.Show("Nothing to Search!", "", MessageBoxButtons.OK);
        }
        else
        {
            if (radioButton2.Checked == true)
            {

                if(textBox1.Text == "dental clinic")
                {


                    frmGraphics.DrawLine(myPen, path1.Location.X, path1.Location.Y, path2.Location.X, path2.Location.Y);
                    Thread.Sleep(500);
                    frmGraphics.DrawLine(myPen, path2.Location.X, path2.Location.Y, path3.Location.X, path3.Location.Y);
                    Thread.Sleep(500);
                    frmGraphics.DrawLine(myPen, path3.Location.X, path3.Location.Y, path4.Location.X, path4.Location.Y);


                    lbres.Text = "Dental Clinic";
                    lbloc.Text = "OutPatient Department";
                    OPDView opdfrm = new OPDView();
                    dview = opdfrm;
                }
                else
                {
                    MessageBox.Show("No Results Found!", "", MessageBoxButtons.OK);
                }
                myPen.Dispose();
                frmGraphics.Dispose(); 
                return;

          }
       }

I have 4 buttons which a had rename as path1 - path4 and wish to connect them all on the line. I need some help about this, thanks.


回答1:


The code has more issues but I'll only hint at them at the end..

The error you probably trip on is in not getting the coordinates right.

PictureBox is not a container control, so whatever you put on top of it is not sitting inside it. Test by moving the PB: The Buttons won't move with it.. - Note that this is different from putting a Button onto a Panel or a GroupBox..

There are two ways to fix it:

  • You can make the Buttons children of the PictureBox in code or
  • You can calculate the correct positions.

Here is how to make the Button children of the PB:

path1.Parent = pictureBox1;    
path2.Parent = pictureBox1;    
path3.Parent = pictureBox1;

Note that you will have to adopt the code that moces the buttons now

Or you correct the position taking the PB's location into account:

Point np1 = Point.Subtract(path1.Location, (Size)pictureBox1.Location);
Point np2 = Point.Subtract(path2.Location, (Size)pictureBox1.Location);
Point np3 = Point.Subtract(path3.Location, (Size)pictureBox1.Location);
frmGraphics.DrawLine(myPen, Point.Empty, np1 , np2);
...

Another issue is thatthe way to draw, using control.CreateGraphics is not persistent. In fact it is almost always wrong! The results will disappear at each window resize etc.. The better way is to draw in the Picturebox.Paint event using the e.Graphics parameter.

I also wonder what the Buttons are there for in the first place? You can create a List<Point> and draw without them just as well.

Also using Thread.Sleep(500) for an animation will freeze the UI thread. Instead use a Timer to go through the list of points. It you need a fixed number of ways to animate you can create a Dictionary<string, List<Point>> to hold them all..

Update

To create a list of points is simple. Declare it at class level:

List<Point> way = new List<Point>();

And fill it when you know the data:

way.Add(new Point(100, 100));
way.Add(new Point(150, 100));
way.Add(new Point(150, 200));
way.Add(new Point(10, 200));
way.Add(new Point(10, 220));
way.Add(new Point(50, 220));
way.Add(new Point(50, 250));

Also create a Timer and set its Interval. In its Tick event you move up a pointer to the current segment and call the Paint event be invalidating the PictureBox:

void aTimer_Tick(object sender, EventArgs e)
{
    point = Math.Min(point + 1, way.Count);
    pictureBox1.Invalidate();
    if (point >= way.Count) aTimer.Stop();
}

And in the Paint event of the PictureBox you draw the path from start to the current index:

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    using (Pen pen = new Pen(Color.DarkGoldenrod, 2.5f))
        for (int i = 1; i < point; i++) e.Graphics.DrawLine(pen , way[i - 1], way[i]);
}

I left out a few checks and you will want to think of a way to store or construct the point lists..

You also may want to improve the animation by drawing smaller segments. For this you could add more points but using a function will be more flexible..:

int stepLen = 10;  // draw 10 pixels on each tick

List<Point> SlowWay(List<Point> way)
{
    List<Point> slow = new List<Point>();

    for (int i = 1; i < way.Count; i++ )
    {
        int dx = way[i].X - way[i - 1].X;
        int dy = way[i].Y - way[i - 1].Y;
        float len = (float)Math.Sqrt(dx*dx+dy*dy);
        int stepCount = (int)(len / stepLen);
        float stepX = dx / stepCount;
        float stepY = dy / stepCount;

        slow.Add(way[i - 1]);
        for (int s = 0; s < stepCount; s++)
            slow.Add(new Point((int)(way[i - 1].X + s * stepX), 
                               (int)(way[i - 1].Y + s * stepY)));
    }
    slow.Add(way[way.Count - 1]);
    return slow;
}



来源:https://stackoverflow.com/questions/34995588/draw-a-line-using-buttons-as-a-coordinates-on-a-picturebox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!