BackgroundWorker, update gui, static method
我有一个应用程序,我正在使用后台工作人员启动一些序列。有时需要更新GUI。
我有一个静态类,其中引用了一些GUI对象。在我的逻辑中,我想从这个静态类调用方法,使用一些参数,分析它并更新GUI。但是我有"调用线程不能访问这个对象,因为另一个线程拥有它。"异常。
在第一个线程中设置变量:
1 2 3 4
| public static void SetCardHand(ref CardHand ch)
{
cardHand = ch;
} |
从后台工作线程调用的方法:
1 2 3 4 5 6 7 8
| private static void SetCoveredCardsPlayer0(int cardsNumber)
{
if (cardsNumber < 1)
cardHand.imgCard1.Source = null;
else
cardHand.imgCard1.Source = (ImageSource)WindowManager.Instance.CardsGUI.CardsDictionary["T1"];
} |
如何让这个方法改变图形用户界面?
编辑
这不是靠窗上课。有点像演讲者。
编辑2
这是一个纸牌游戏。我是在后台工作人员中启动它的,我需要在每次交易后更新图像源(代表卡)。
- 根据您的应用程序设计,大纲为backgroundworker.workerReportsProgress=true,并订阅将在UI线程上运行的ProgressChanged。
- 您必须详细说明您要呼叫的setcoveredcardsplayer0的位置。它应该来自已完成的或ProgressChanged事件处理程序——如果不是,您将得到该异常。如果您对已完成或ProgressChanged事件处理程序以外的其他对象进行调用,请查看为下面的答案发布的授权。
在更新UI之前,必须将控制权传递回主线程。背景工作者使这相当容易。
创建BackgroundWorker时,设置WorkerReportsProgress = true。
订阅ProgressChanged事件,并将更新UI的逻辑放入该事件中。
在您的DoWork事件中,当您想要更新GUI时,调用myBackgroundWorker.ReportProgress(0, someObject),其中"someobject"是您想要操作的数据块。在您的情况下,可能是您分配给cardHand.imgCard1.Source的ImageSource。
在ReportProgress事件中,您可以通过e.UserState访问您经过的对象。在使用它之前,您需要将它转换回一个ImageSource。
您可以将您的if (cardsNumber < 1)逻辑保留在DoWork事件中,但是当您想将Source设置为ImageSource或null时,您需要将该值传递给ProgressChanged事件,以实际更新UI元素。
- 很好,但我需要一些不同类型的更新。怎么做?
- @用户1736332如果在线程运行时必须在不同的时间用不同的数据更新多个控件,则必须以某种方式拆分逻辑。您的DoWork事件可以在需要时将数据发送到ProgressChanged事件,然后您可以在ProgressChanged中使用逻辑来测试它接收到的数据,并根据该数据更新正确的控件。或者,您可以等到完成了DoWork事件,并将所有数据传递给RunWorkerCompleted事件(使用Tuple或自定义类),然后从中更新所有UI组件。