WPF强制重绘画布

ohm*_*ama 10 c# wpf wpf-controls redraw

好的,在Windows窗体中,您可以使用它.refresh()来在元素上生成重绘事件.WPF中是否有类似的解决方案?

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

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

如果有可能,我想在c#中找到解决方案.谢谢.

小智 31

这就是你要找的......

element.InvalidateVisual();
Run Code Online (Sandbox Code Playgroud)


Jon*_*ina 12

这项工作对我来说......

element.UpdateLayout();
Run Code Online (Sandbox Code Playgroud)


Sim*_*ier 8

您可能想要使用Dispatcher对象.我建议你看一下Shawn Wildermuth的文章:使用Dispatcher构建更多响应式应用程序(MSDN杂志2007年10月).

  • 这不是100%的解决方案,但它使我开始朝着正确的方向前进.这最终起作用:`canvas.Dispatcher.Invoke(emptyDelegate,DispatcherPriority.Render);`其中emptyDelegate是`Action emptyDelegate = delegate {};` (11认同)
  • "使用Dispatcher构建更多响应式应用程序"链接不再有效. (2认同)

Pet*_*iho 5

如果没有一个好的最小、完整和可验证的代码示例来清楚地显示您在做什么,就不可能确定这里的最佳答案是什么。但是,根据您的描述,似乎迷宫生成算法正在 UI 线程中执行,阻止 UI 更新自身。

就像在 Winforms 的情况下一样,人们很想调用Refresh()Application.DoEvents()之类的方法,这里真正的问题是您正在阻塞 UI 线程。解决这个问题的正确方法是,不要那样做

有很多替代方案,如果没有更详细的问题,就无法知道在您的情况下什么是最佳方法。但是,两种最常用且最可能是合适的技术是使用BackgroundWorker,或Task.Run()Progress<T>类结合使用。在任何一种情况下,您的算法都在不同的线程中运行,定期将更新传递给 UI 线程(例如,每个矩形、每十个矩形等等)。UI 线程接收更新,将数据添加到视觉对象,然后返回等待下一次更新。

BackgroundWorker并且Progress<T>两者都提供了自动将数据编组回 UI 线程的内置机制。唯一需要注意的是,无论您使用哪个类,都需要在 UI 线程上创建该类的实例。由于它们需要在开始执行异步工作之前进行设置,因此这通常不是问题;它是免费的。

如果您这样做,您将不需要任何 hacks,例如到目前为止在这里建议的三种不同的 hacks(其中两个似乎不太可能适用于“我已经阻止了我的 UI 线程,现在怎么办?” 无论如何)。