使用按钮作为 PictureBox 上的坐标绘制一条线

Draw a line using buttons as a coordinates on a PictureBox

目前我正在根据显示的图像制作 Rooms/Office 的搜索程序。

我在程序上遇到问题,我想在 2D 地图上显示一条线,其中将使用按钮连接线的每个坐标。但是在搜索一个房间后,不会出现任何行。

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;

          }
       }

我有 4 个按钮,它们已重命名为路径 1 - 路径 4,并希望将它们全部连接起来。我需要一些帮助,谢谢。

代码有更多问题,但我只会在最后提示它们..

您可能遇到的错误是坐标不正确。

PictureBox 不是容器控件,所以无论你放在 top 上面什么都是 not sitting 里面它。通过移动 PB 进行测试:Buttons 不会随之移动 .. - 请注意,这不同于将 Button 放在 [=20= 上] 或 GroupBox..

有两种修复方法:

  • 您可以在代码中创建 PictureBoxButtons 子代或
  • 您可以计算出正确的位置。

以下是创建 PB 的 Button 子项的方法:

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

请注意,您现在必须采用移动按钮的代码

或者您根据 PB 的位置更正位置:

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);
...

另一个问题是使用control.CreateGraphics的绘制方式不持久。事实上,它几乎总是错的!结果将在每次 window 调整大小等时消失。更好的方法是使用 e.Graphics 参数在 Picturebox.Paint 事件中绘制。

我也想知道 Buttons 最初是做什么用的?您可以创建一个 List<Point> 并在没有它们的情况下进行绘制。

同时对动画使用 Thread.Sleep(500) 将冻结 UI 线程。而是使用 Timer 遍历点列表。如果你需要固定数量的动画方式,你可以创建一个 Dictionary<string, List<Point>> 来容纳它们..

更新

创建点列表很简单。在 class 级别声明它:

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

知道数据后填写:

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));

同时创建一个计时器并设置它的间隔。在它的 Tick 事件中,您向上移动一个指向当前段的指针并调用 Paint 事件使 PictureBox 无效:

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

然后在 PictureBox 的 Paint 事件中绘制从开始到当前索引的路径:

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]);
}

我遗漏了一些检查,你会想出一种方法来存储或构建点列表..

您可能还想通过绘制更小的片段来改进动画效果。为此,您可以添加更多点,但使用函数会更灵活..:[=​​33=]

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;
}