【问题标题】:Draw a line using buttons as a coordinates on a PictureBox使用按钮绘制一条线作为 PictureBox 上的坐标
【发布时间】:2016-01-26 20:09:41
【问题描述】:

目前我正在根据显示的图像制作房间/办公室的搜索程序。

我想在 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 个按钮,它们被重命名为 path1 - path4,并希望将它们全部连接起来。我需要一些帮助,谢谢。

【问题讨论】:

    标签: c# winforms coordinates picturebox


    【解决方案1】:

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

    您可能犯的错误是没有正确获取坐标。

    PictureBox 不是容器控件,所以无论您放在 顶部 它的 不是 坐在 里面 它。通过移动 PB 进行测试:Buttons 不会移动 .. - 请注意,这与将 Button 放在 PanelGroupBox 上不同..

    有两种修复方法:

    • 您可以在代码中将Buttons 设为PictureBox 的子代或
    • 您可以计算出正确的位置。

    下面是如何制作 PB 的子按钮:

    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的绘制方式不是持久的。事实上,它几乎总是错的!结果将在每次调整窗口大小等时消失。更好的方法是使用e.Graphics 参数绘制Picturebox.Paint 事件。

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

    同时使用Thread.Sleep(500) 动画会冻结UI 线程。而是使用Timer 浏览点列表。如果您需要固定数量的动画方式,您可以创建一个Dictionary<string, List<Point>> 来保存它们。

    更新

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

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

    我遗漏了一些检查,您将需要考虑一种存储或构造点列表的方法..

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

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

    【讨论】:

    • 似乎连接我一直困惑的那些线的唯一方法是计算位置和PB的位置。我放置了按钮,以便我更容易找到每个房间,这可能是我的错误,我正在尝试根据您的回答重新编辑程序。感谢先生的帮助。
    • 如果您有问题,尽管问!如何设置按钮位置?它们是固定的吗?我肯定会选择点列表并使用按钮进行绘图,除非它们在 UI 中提供其他功能。您可以通过在 MouseClick 事件中记录 e.location 在测试模式下创建这样的列表。跨度>
    • 线路现在可以连接到按钮,但我仍然对再次搜索另一个房间并再次显示新线路或路径方式后线路不会消失的事情感到困惑。你能告诉我一个用于创建列表的 sn-p 吗?
    • 是的,但请尽量回答所有问题!您现在如何放置或移动按钮?地图上有多少种方式?
    • 我已经添加了一个简单动画的代码,看看你是否喜欢。
    猜你喜欢
    • 2019-02-06
    • 2011-09-08
    • 1970-01-01
    • 1970-01-01
    • 2011-11-13
    • 2021-11-26
    • 2018-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多