清除图片框上绘制的矩形以显示移动
本文关键字:显示 移动 绘制 清除 | 更新日期: 2023-09-27 18:06:12
我尝试在我的应用程序中模拟火车运动,所以我使用以下代码创建火车地图:
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();
}
所以你可以看到上面我调用我的函数,我在我的 pagload 创建一个线程,所以线程做一个重要的操作,它调用函数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)。所以我必须在我的地图上显示火车。我调用我的图片框的**Paint事件:
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 **的所有位置并绘制它们,但我在这里有一个大问题,我需要显示我的火车的运动,我应该清除我的火车的旧位置,但我不知道我该怎么做??我的火车的所有位置都画在我的画框上!!你知道吗?
如果您创建两个相同大小的PictureBoxes
:另一个用于地图,另一个用于火车,顶部使用透明度。因为它们大小相同,所以位置也匹配:https://stackoverflow.com/a/9158849/2538037
当表单加载后,您启动BackgroundWorker
,它通过ProgressChanged
事件将列车和位置更新到顶部PictureBox
。您可以使用它来绘制图像,然后将其设置为顶部PictureBox
。您可以对它使用一些计时,这样它就会计算一个新的更新的火车图像,比如每2秒。您还应该在更改新图像后对旧图像使用Dispose()
。记住使用Invalidate()
来更新图片框
如果您使用pictureBoxMetroMap.Image =
将图像分配给PictureBox
,那么您应该能够在PictureBox
表面上绘制而不会干扰该图像。
现在,如果你手动绘制额外的"地图"图形,那么你必须在每个Paint
周期继续这样做。这意味着Paint
必须处理重绘"地图"细节,以及刷新列车图形以模拟运动。
确保负责识别或记录列车运行数据的代码调用pictureBoxMetroMap.Invalidate();
来触发Paint
调用。