C# 在picturebox上清除绘制的矩形以显示移动

C# 在picturebox上清除绘制的矩形以显示移动,c#,multithreading,winforms,C#,Multithreading,Winforms,我尝试在我的应用程序中模拟列车运动,因此我使用以下代码创建列车地图: public void DrawMap() { Bitmap map = new Bitmap(pictureBoxMetroMap.Size.Width, pictureBoxMetroMap.Size.Height); var graph = Graphics.FromImage(map); List<Point> lst

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

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

        }
正如您在上面看到的,我调用了我的函数,并在我的页面加载中创建了一个线程,因此该线程执行了一个重要的操作,它调用了一个函数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**的所有位置并绘制它们,但我这里有一个大问题,我需要显示我的列车的运行,我应该清除我的列车的旧位置,但我不知道如何才能做到???我的火车的所有位置都画在我的图片盒上!!有什么想法吗


致以最诚挚的问候

如果您已使用
pictureBoxMetroMap.image=
将图像分配给
PictureBox
,则您应该能够在不干扰该图像的情况下绘制到
PictureBox
表面

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


确保负责识别或记录列车运行数据的代码正在调用
pictureBoxMetroMap.Invalidate()
触发
绘制
调用。

如果创建两个大小相同的
图片框
:另一个用于地图,另一个用于火车,使用顶部的透明度。由于大小相同,因此位置也匹配:


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

旁注:不要在
Paint
处理程序中使用
CreateGraphics
。你可以使用
e.Graphics
免费获得。谢谢,我改了that@DonBoitnott你贴出来的答案是有效的,但它清除了整个地图,我需要清除地图上的火车什么是“地图”?是加载并分配给
PictureBox.image
的图像吗?或者它是在代码中绘制在
图片盒上的东西吗?@DonBoitnott是的,地图就是分配给pbit的图像。它工作,但它清除了整个地图,我需要清除地图上的火车。所以你不认为用面板代替pb也有同样的问题吗(它清除了整个地图,我需要清除地图上的火车)我必须使用pb,因为我的地图比例太大了,我需要滚动,而面板上没有这个滚动。我想试试你的方法,但是我怎样才能将两个图片框映射到地图上?我想它可以工作,但是你想清除地图上的火车,因此你需要将火车和地图图像分开。我提供了上面关于如何使用这两个PictureBox的链接。使用设计器将另一个
PictureBox
放在旧的上面,并检查大小是否匹配。效果很好,但在背景图像中我有一些标签,当我将火车PictureBox放在上面时,它们消失了!!!为什么?您可以在DrawMap功能中看到我的标签,请尝试将标签添加到新的上部图片框中。
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);

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

            }
        }