Picturebox中的绘制形状并不清晰

时间:2014-06-03 10:28:04

标签: c# multithreading

我正试图展示一张在地图上移动的火车。让我解释一下我的方法,我在Picturebox上绘制地图地图,我的火车在另一个图片框火车上,我将列车 PictureBox放在地图图片框上。

更多详情:https://stackoverflow.com/a/9158849/2538037

所以我在这里使用两个函数:

 public void DrawMap()
        {

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

                    graph.DrawString(ObjStationRepository.FindBy(i => i.Id == t.StationId).First().Name, pictureBoxMetroMap.Font, Brushes.White, t.XLocation +40, t.YLocation +50);

                }
            }

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

                    graph.DrawString(ObjStationRepository.FindBy(i => i.Id == t.StationId).First().Name, pictureBoxMetroMap.Font, Brushes.White, t.XLocation - 50, t.YLocation - 30);
                }
            }

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


        }

此功能绘制地图,此功能将我的列车绘制在另一个图片框上:

 public void DrawOnlineTrain()
        {
            var graph = Graphics.FromImage(map);

            if (OnlineTrainList.Count > 0)
            {

                foreach (OnlineTrain t in OnlineTrainList.ToList())
                {
                   // graph.Dispose();
                    Rectangle rectTrainState = new Rectangle(t.XTrainLocation.Value - 3,
                                                             t.YTrainLocation.Value - 3,
                                                             7, 7);
                    graph.FillRectangle(RedBrush, rectTrainState);
                }
            }
            pictureBoxonlineTrain.Image = map;



    }

所以我使用线程来更新 Train 图片框,我在form_load中调用线程:

 private void frmMain_Load(object sender, EventArgs e)
        {
            pictureBoxonlineTrain.Parent = pictureBoxMetroMap;
            map= new Bitmap(pictureBoxMetroMap.Size.Width, pictureBoxMetroMap.Size.Height);
            UpdateListBox = new UpdateListBoxDelegate(this.UpdateStatus);
            // Initialise and start worker thread
            workerThread = new Thread(new ThreadStart(this.GetOnlineTrain));
            workerThread.Start();
}

所以在线程中我启动了一个获取在线列车位置的方法:

  public void GetOnlineTrain()
        {        
           while(true)
            {
                OnlineTrainRepository objOnlineTrainRepository = new OnlineTrainRepository();
                OnlineTrainList = objOnlineTrainRepository.GetAll().ToList();
                objOnlineTrainRepository = null;
                Invoke(UpdateListBox);

            }

        }

在这里,我开始绘制列车 UpdateListBox

 private void UpdateStatus()
        {

            foreach (OnlineTrain onlineTrain in OnlineTrainList.ToList())
            {

              lstLog.Items.Add("Train Id=" + onlineTrain.TrainId + " | Current x position=" + onlineTrain.XTrainLocation + " | Current y position=" + onlineTrain.YTrainLocation);
              pictureBoxonlineTrain.Image = null;

                DrawOnlineTrain();
            }


        }

正如你在这里看到的那样,为了显示运动,我必须清除火车的旧位置,并且我这样做:

pictureBoxonlineTrain.Image = null;

但它不起作用,每个矩形都保留在我的屏幕上?!!!

祝你好运

1 个答案:

答案 0 :(得分:1)

<强> 1。直接解决您的问题

  • 你永远不会清楚位图!请注意,在使用Graphics.FromImage
  • 时,您正在绘制已经存在的所有内容的
  • 您使用同一个Bitmap对象进行所有绘图。所以(结合前一点)你基本上都在map中拥有整个“场景” - 在这种情况下不需要多个PictureBox es!
  • 小心:如果PictureBox刷新您正在绘制,则未完成状态将会显示!您正在操纵显示的图像。

<强> 2。我会做什么

  • 将所有内容渲染到一个缓冲区(您正在使用Bitmap这很好,但可以考虑使用BufferedGraphics
  • 随时随地将其呈现给控件(或Paint事件触发)而非使用PictureBox