[英]C# Why is my picturebox not moving when draw function called by timer?
我正在創建一個簡單的應用程序,它抓取一些與一些機器工具的狀態相關的 XML,這些機器工具正在輸出實時傳感器數據,並使用設備的 X/Y 坐標讓老鼠在屏幕上跳舞。 第一次輪詢機器時,老鼠被放置在正確的位置,但每次繪制函數被后續計時器驅動的事件調用時都不會移動。
我認為這只是因為機器處於待機狀態,唯一的坐標變化是伺服的小抖動,但只是為了檢查我創建了一個隨機數生成器並讓系統使用隨機生成的坐標而不是縮放的 X/Y 數據在。
然后我發現老鼠不動了! 這是我繪制老鼠的函數(有 2 個系統,但我們現在只擔心 'bakugo')我們特別關注 if (dekuWake == false) 和 (bauwake == true); 在這里,我已將值打印到控制台(由計時器驅動),並且“system.drawing.point(s)”顯示為有效(在范圍內和變化中)。
計時器由 form1 中的按鈕啟動。 計時器事件調用輪詢函數,該函數從站點中抓取 XY 變量(請參閱我在此處提出的該函數的問題 - 我在 C# 中使用 XPath 有什么問題? )此時它確定狀態是否為“可用”(它是) 並將 'rat's' 'awake' bool 設置為 true(確定繪制哪些圖像,如果機器處於離線狀態,則 'rat' 留在其框內)然后將坐標縮放到程序窗口的分辨率(通常,正確的現在它正在遍歷輪詢第一次開始時生成的 2 個整數數組。更新坐標函數設置 ImageRat.Bakugo 的 X、Y 坐標並調用 drawRats()。
為什么更改圖像的位置實際上並未重新定位圖片框?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Reflection;
using System.Drawing;
using System.Windows.Forms;
namespace XMLRats3
{
public class Drawing
{
private PictureBox HouseImage;
private PictureBox DekuImage;
private PictureBox BakuImage;
public Drawing(PictureBox house, PictureBox deku, PictureBox baku)
{
HouseImage = house;
DekuImage = deku;
BakuImage = baku;
}
public void ClearRats()
{
HouseImage.Hide();
DekuImage.Hide();
BakuImage.Hide();
}
public void DrawRats(bool DekuWake, bool BakuWake) // Call this function using active status of 2 machines
{
ClearRats();
/*// This shows that the generated coordinates are reaching this point successfully
Console.WriteLine("BAKU X: " + ImageRat.Bakugo.PosX);
Console.WriteLine("BAKU Y: " + ImageRat.Bakugo.PosY);
*/
System.Drawing.Point DekuCoord = new System.Drawing.Point(ImageRat.Deku.PosX, ImageRat.Deku.PosY); // Create a 'System Point' for Deku
System.Drawing.Point BakuCoord = new System.Drawing.Point(ImageRat.Bakugo.PosX, ImageRat.Bakugo.PosY); // Create a 'System Point' for Bakugo
if (DekuWake == false)
{
DekuImage.Hide();
if (BakuWake == false)
{
BakuImage.Hide();
HouseImage.Image = DesktopApp1.Properties.Resources.bothsleep;// set HouseImage to both sleep
}
else
{
BakuImage.Location = BakuCoord;
Console.WriteLine("Point:" + BakuCoord);
//Console.WriteLine("Reaching Relocation condition"); // Ensure we are getting here as animation not working
BakuImage.Show();
//BakuImage.
HouseImage.Image = DesktopApp1.Properties.Resources.dekuSleep; //Set HouseImage to DekuSleep
}
}
else //DekuWake == true
{
DekuImage.Show();
if (BakuWake == true)
{
HouseImage.Image = DesktopApp1.Properties.Resources.nosleep;//Set House image to nosleep
BakuImage.Location = DekuCoord;
DekuImage.Show();
BakuImage.Location = BakuCoord;
BakuImage.Show();
}
else
{
BakuImage.Hide();
HouseImage.Image = DesktopApp1.Properties.Resources.bakusleep;// Set house image to bakusleep
DekuImage.Location = DekuCoord;
DekuImage.Show();
}
}
HouseImage.Show(); // Out here as it should always happen
}
}
}
好的,所以我沒有關於如何解決這個問題的確切答案,但我可以告訴你它為什么會發生,並為你指明一些可以幫助你的知識的方向。
在我編寫這段代碼的時候,我(現在仍然)對 C# 和多線程應用程序的概念非常陌生。
這是一個糟糕的軟件架構問題。 這里的問題是在 c# 中只能從單個線程更新 UI,並且由於計時器在另一個線程中運行,因此不允許從計時器調用的任何內容更新 UI。 我認為可以使用委托深入到 UI 線程中,盡管我還沒有對此進行足夠的研究,無法為您提供有關如何完成的確切信息。
希望這會幫助那些為我的問題加注星標的人! 如何從另一個線程更新 GUI?
假設您使用的是來自不同類的計時器,該類占用的線程與主線程不同,對於使用對象的計時器,您應該將該對象添加為“同步對象”之一。 所以假設你的定時器叫做timer1,在你設置定時器屬性的方法中,你應該寫下面這行代碼
timer1.SynchronizingObject = yourPictureBox;
我希望能解決你的問題
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.