2011-05-11 71 views
7

好的,在Windows窗体中,您可以使用.refresh()在元素上产生重绘事件。 WPF中有类似的解决方案吗?WPF强制重绘画布

我正在做什么的解释,我正在绘制一个画布对象的迷宫,并且希望看到迷宫画出来(所以我可以看到进展),而不是等待28分钟的解决方案突然出现。我在画布上绘制了一系列Rectangle s。刷新应该放在矩形还是画布上?

这里是最近的输出: http://imgur.com/ftFOv

我想在C#中的解决方案,如果这是可能的。谢谢。

回答

7

您可能想要使用Dispatcher对象。我建议你看看这个肖恩Wildermuth的文章:Build More Responsive Apps With The Dispatcher(MSDN杂志2007年10月)。

+9

这不是100%的解决方案,但它使我朝着正确的方向前进。这最终是什么工作:'canvas.Dispatcher.Invoke(emptyDelegate,DispatcherPriority.Render);'where emptyDelegate是'Action emptyDelegate = delegate {};' – ohmusama

+0

谢谢,西蒙,你今天早些时候编辑。我正在阅读这篇文章。 – philologon

+2

“使用调度程序构建更多响应式应用程序”的链接不再有效。 –

26

这是你正在寻找...

element.InvalidateVisual(); 
+0

这很好,谢谢@亚当 – J3soon

11

这个工作对我来说是什么?

element.UpdateLayout(); 
2

没有好的Minimal, Complete, and Verifiable code example清楚自己在做什么表现,这是不可能的确切知道这里最好的答案是什么。但是,从您的描述中,听起来好像迷宫生成算法正在UI线程中执行,阻止UI自行更新。

正如在的WinForms,那里的人们很有诱惑力的调用方法,如Refresh()Application.DoEvents(),这里真正的问题的情况是,您阻止UI线程正确修复方法就是,不要那样做

有很多的选择,没有一个更详细的问题,没有办法知道什么是你的情况下最好的办法。然而,两种最常用和最可能合适的技术是使用BackgroundWorkerTask.Run()Progress<T>类别的组合。无论哪种情况,您的算法都运行在不同的线程中,并定期将更新传递给UI线程(例如,每个矩形,每十个矩形,等等)。 UI线程接收更新,将数据添加到视觉效果,然后返回等待下一次更新。

BackgroundWorkerProgress<T>都提供了自动将数据封送回UI线程的内置机制。唯一需要注意的是,无论您使用哪些类,都需要在UI线程上创建该类的实例。由于在开始执行异步工作之前需要设置它们,所以这通常不是问题;它是免费的。

如果你这样做,你将不需要任何黑客,比如迄今为止在这里提出的三种不同的黑客(其中两项似乎不适用于“我已经阻止我的UI线程,现在什么?“场景)。