【问题标题】:WPF forcing redraw of canvasWPF强制重绘画布
【发布时间】:2011-05-11 04:21:42
【问题描述】:

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

解释我在做什么,我正在画布对象上绘制一个迷宫,并且想观察迷宫的绘制(这样我可以看到进度),而不是等待 28 分钟才能突然解决出现。我正在画布上用一系列Rectangles 绘制块。刷新应该在矩形还是画布上?

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

如果可能的话,我想要一个 c# 中的解决方案。谢谢。

【问题讨论】:

    标签: c# wpf wpf-controls redraw


    【解决方案1】:

    这就是你要找的……

    element.InvalidateVisual();
    

    【讨论】:

      【解决方案2】:

      这对我有用...

      element.UpdateLayout();
      

      【讨论】:

        【解决方案3】:

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

        【讨论】:

        • 这不是 100% 的解决方案,但它让我朝着正确的方向前进。这最终是有效的:canvas.Dispatcher.Invoke(emptyDelegate, DispatcherPriority.Render); 其中 emptyDelegate 是 Action emptyDelegate = delegate { };
        • 感谢 Simon,您今天早些时候所做的编辑。我现在正在阅读这篇文章。
        • “使用 Dispatcher 构建更具响应性的应用程序”的链接不再有效。
        • 它有效,但您必须浏览到 2007 年并单击 10 月。我没有故意放置确切的链接(加上它是一个 CHM)以避免将来损坏的链接。
        【解决方案4】:

        如果没有一个好的Minimal, Complete, and Verifiable code example 来清楚地表明你在做什么,就不可能确定这里的最佳答案是什么。但是,根据您的描述,迷宫生成算法似乎在 UI 线程中执行,从而阻止了 UI 自行更新。

        就像在 Winforms 的情况下,人们很想调用像 Refresh()Application.DoEvents() 这样的方法,这里真正的问题是你阻塞了 UI 线程正确的方法是不要这样做

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-21
          • 2013-01-24
          • 2015-03-16
          相关资源
          最近更新 更多