【问题标题】:Clear drawn rectangle on picturebox to show movement清除图片框上绘制的矩形以显示移动
【发布时间】:2014-06-02 16:33:36
【问题描述】:

我尝试在我的应用程序中模拟火车运动,所以我使用此代码创建火车地图:

 public void DrawMap()
        {
            Bitmap map = new Bitmap(pictureBoxMetroMap.Size.Width, pictureBoxMetroMap.Size.Height);
            var graph = Graphics.FromImage(map);
            List<Point> lstPointLeft = new List<Point>();
            foreach (var t in lstSensorLeft)
            {
                Point objPoint = new Point(t.XLocation, t.YLocation);
                lstPointLeft.Add(objPoint);
                Rectangle rectSens = new Rectangle(t.XLocation, t.YLocation, 3, 3);
                try
                {
                    graph.FillRectangle(whiteBrush, rectSens);
                }
                catch (Exception ea)
                {

                }
                if (t.StationId != null)
                {
                    Rectangle rectEhsansq = new Rectangle(t.XLocation - 6, t.YLocation - 6, 12, 12);
                    graph.FillRectangle(blueBrush, rectEhsansq);
                    Label ObjLable = new Label();
                    ObjLable.ForeColor = Color.Transparent;
                    ObjLable.Location = new Point(t.XLocation+40, t.YLocation +50);
                    ObjLable.Text = ObjStationRepository.FindBy(i => i.Id == t.StationId).First().Name;
                    ObjLable.BackColor = Color.Transparent;
                    ObjLable.Width = 70;
                    pictureBoxMetroMap.Controls.Add(ObjLable);

                }
            }

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

            foreach (var t in lstSensorRight)
            {
                Point objPoint = new Point(t.XLocation + 30, t.YLocation + 30);
                lstPointRight.Add(objPoint);
                Rectangle rectSens = new Rectangle(t.XLocation + 30, t.YLocation + 30, 3, 3);
                graph.FillRectangle(whiteBrush, rectSens);
                if (t.StationId != null)
                {
                    Rectangle rectPosition = new Rectangle(t.XLocation + 24, t.YLocation + 24, 12, 12);
                    graph.FillRectangle(blueBrush, rectPosition);

                    Label ObjLable = new Label();
                    ObjLable.ForeColor = Color.Transparent;
                    ObjLable.Location = new Point(t.XLocation - 50, t.YLocation - 30);
                    ObjLable.Text = ObjStationRepository.FindBy(i => i.Id == t.StationId).First().Name;
                    ObjLable.BackColor = Color.Transparent;
                    ObjLable.Width = 70;
                    pictureBoxMetroMap.Controls.Add(ObjLable);

                }
            }

            graph.DrawLines(pLine, lstPointLeft.ToArray());
            graph.DrawLines(pLine, lstPointRight.ToArray());
            pictureBoxMetroMap.Image = map;

           // ShowOnlineTrain();
            //Thread newThread = new Thread(new ThreadStart(ShowOnlineTrain));

            //newThread.Start();

        }

如您所见,DramMap 绘制了我的火车地图,我在我的应用程序的 page_load 中调用了此函数,如下所示:

private void frmMain_Load(object sender, EventArgs e)
    {
        UpdateListBox = new UpdateListBoxDelegate(this.UpdateStatus);
        // Initialise and start worker thread
        workerThread = new Thread(new ThreadStart(this.ShowOnlineTrain));
        workerThread.Start();
        DrawMap();
    }

正如你在上面看到的,我调用了我的函数并在我的 pageload 中创建了一个线程,所以该线程执行了一项重要操作,它调用了一个函数 ShowOnlineTrain,这个函数获取在线火车的位置,我应该在我的地图上显示这些火车:

List<OnlineTrain> OnlineTrainList = new List<OnlineTrain>();
        public void ShowOnlineTrain()
        {

            OnlineTrainRepository objOnlineTrainRepository = new OnlineTrainRepository();


           while(true)
            {
                OnlineTrainList = objOnlineTrainRepository.GetAll().ToList();

                    Invoke(UpdateListBox);

            }



           }
  private void UpdateStatus()
        {
            lstLog.Items.Add("Train Id=" + OnlineTrainList.First().TrainId + " | Current x position=" + OnlineTrainList.First().XTrainLocation + " | Current y position=" + OnlineTrainList.First().YTrainLocation);

        }

这个函数获取在线火车的位置。所以 OnlineTrainList ** 有在线火车的位置(即 x 和 y 和 trainId)。所以我必须在我的地图上显示火车。我调用 **我的图片框的绘制事件:

  private void pictureBoxMetroMap_Paint(object sender, PaintEventArgs e)
        {
            if (OnlineTrainList.Count > 0)
            {
                foreach (OnlineTrain t in OnlineTrainList)
                {
                    var g = pictureBoxMetroMap.CreateGraphics();
                    Rectangle rectTrainState = new Rectangle(t.XTrainLocation.Value - 3,
                                                             t.YTrainLocation.Value - 3,
                                                             7, 7);
                    g.FillRectangle(RedBrush, rectTrainState);
                }

            }
        }

它获取**OnlineTrainList **的所有位置并绘制它们,但是我这里有一个大问题,我需要显示我的火车的运动,我应该清除我的火车的旧位置,但我没有知道我该怎么做???我的火车的所有位置都画在我的图片框上!!有什么想法吗?

最好的问候

【问题讨论】:

  • 旁注:不要在Paint 处理程序中使用CreateGraphics。你可以使用e.Graphics免费获得。
  • 谢谢我改了
  • @DonBoitnott 您发布的答案有效,但它会清除整个地图,我需要清除地图上的火车
  • 什么是“地图”?是加载并分配给PictureBox.Image 的图像吗?还是代码中的PictureBox 被绘制的内容?
  • @DonBoitnott 是的,地图就是分配给 pb 的图像

标签: c# multithreading winforms


【解决方案1】:

如果您创建 2 个相同大小的 PictureBoxes:另一个用于地图,另一个用于火车,使用顶部的透明度。由于它们的大小相同,因此位置也匹配:https://stackoverflow.com/a/9158849/2538037

当表单加载后,您启动一​​个BackgroundWorker,它通过ProgressChanged-事件将火车和位置更新到顶部PictureBox。您可以使用它来绘制图像,然后将其设置为顶部PictureBox。你可以在它上面使用一些时间,所以它会像每 2 秒一样计算一个新的更新的火车图像。在更换新图像后,您还应该对旧图像使用Dispose()。请记住使用Invalidate(),以便更新图片框。

【讨论】:

  • 我想试试你的方法,但是我怎么能映射两个图片框呢?
  • 我觉得可以,但是你想清除地图上的火车,所以你需要把火车和地图图像分开。我在上面提供了有关如何使用这两个图片框的链接。使用设计器将另一个 PictureBox 放在旧的上面,并检查大小是否匹配。
  • 效果很好,但是在背景图像中我有一些标签,当我把火车图片框放在上面时,它们消失了!!!为什么?你可以在 DrawMap 函数中看到我的标签
  • 尝试将标签添加到新的上部图片框。
【解决方案2】:

如果您已使用pictureBoxMetroMap.Image = 将图像分配给PictureBox,那么您应该能够在PictureBox 表面上绘图而不会干扰该图像。

现在,如果您要手动绘制其他“地图”图形,那么您必须在每个Paint 循环中继续这样做。这意味着Paint 必须处理重绘“地图”细节,以及刷新火车图形以模拟运动。

确保负责识别或记录火车运动数据的代码正在调用pictureBoxMetroMap.Invalidate(); 以触发Paint 调用。

【讨论】:

  • 它可以,但是它会清除整个地图,我需要清除地图上的火车
  • 所以你不觉得用panel代替pb有同样的问题(它会清除整个地图,我需要清除地图上的火车)
  • 我必须使用pb,因为我的地图比例太大,我需要滚动,而面板没有这个滚动
猜你喜欢
  • 1970-01-01
  • 2012-05-13
  • 2018-10-23
  • 1970-01-01
  • 1970-01-01
  • 2018-04-16
  • 1970-01-01
  • 1970-01-01
  • 2011-04-17
相关资源
最近更新 更多