清除图片框上的绘制矩形以显示移动

时间:2014-06-02 16:33:37

标签: c# multithreading winforms

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

 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 **的所有位置并绘制它们,但我在这里有一个大问题,我需要显示我的火车的运动,我应该清除我的火车的旧位置,但我不知道我该怎么办?我的火车的所有位置都画在我的照片箱上!!任何想法?

祝你好运

2 个答案:

答案 0 :(得分:1)

如果您使用PictureBoxpictureBoxMetroMap.Image =指定了图片,那么您应该可以在PictureBox面上绘图而不会打扰该图像。

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

确保负责识别或记录列车移动数据的代码正在呼叫pictureBoxMetroMap.Invalidate();以触发Paint来电。

答案 1 :(得分:1)

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

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