Draw a line using buttons as coordinates on the PictureBox

I am currently making a room / office search program based on the image shown.

enter image description here

I am having problems with a program that I want to show on a 2D map where buttons will be used to connect each line coordinate. But after searching the room there are no lines to 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 renamed as path1 - path4 and would like to connect them all on a line. I need help, thanks.

+1


source to share


1 answer


There are more problems in the code, but I only hint at them at the end.

The error you are probably making the trip with is not getting the correct coordinates.

PictureBox

not an element of the container control, so whatever you put on top , not sitting inside . Test by moving PB: Buttons

won't move with it .. - Note that this is different from placing Button

on Panel

or GroupBox

..

There are two ways to fix this:

  • You can make Buttons

    children PictureBox

    in code or
  • You can calculate the correct positions.

Here's how to make Button PB child buttons:

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

      

Note that you will need to accept the code which will now copy the buttons

Or do you fix the position taking into account the PB location:

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 problem is that the drawing method using control.CreateGraphics

is not constant. In fact, this is almost always wrong! The results will disappear whenever the window is resized, etc. The best way is to paint on an event Picturebox.Paint

using a parameter e.Graphics

.

I also wonder what is Buttons

the first thing ? You can create List<Point>

and paint without them in exactly the same way.

Also using Thread.Sleep(500)

for animation will freeze the UI thread. Instead, use Timer

to view the list of points. You need a certain number of ways to animate, you can create Dictionary<string, List<Point>>

to hold them all.



Update

Creating a list of points is easy. Declare it at the class level:

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

      

And fill it in 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 your Tick event, you move the pointer to the current segment and call the Paint event with an invalid 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 for the PictureBox, you draw the path from the 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 skipped a few checks and you might want to think about a way to store or create lists of points.

You can also improve the animation by drawing smaller segments. You could add more points for this, but the use of the function would 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;
}

      

enter image description here

0


source







All Articles