【问题标题】:Invalidate own WPF control使自己的 WPF 控件无效
【发布时间】:2012-01-24 09:39:03
【问题描述】:

我有一个几天前制作的自定义 WPF 控件:

 public class MapContext : FrameworkElement{
     //....
      protected override void OnRender(DrawingContext dc) {
         // Draw the map
         if (mapDrawing != null) dc.DrawDrawing(mapDrawing);
 }

mapDrawing 绘图在另一个线程中更新,在该线程中计算所有要显示的几何图形,然后该线程通过调用 InvalidateVisual() 更新 UI:

Application.Current.Dispatcher.Invoke(DispatcherPriority.Render, new Action(delegate { InvalidateVisual(); }));

在InvalidateVisual,MSDN documentation 说:

使元素的渲染无效,并强制进行全新的布局传递。布局循环完成后调用 OnRender。

这不是我想要的行为,因为 MapContext 控件布局没有改变。只有里面的图变了。

问题 是否有适当的方法来强制调用 OnRender 方法而不进行完整的布局传递?

提前致谢

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    不,没有布局通道就无法强制重新渲染。 由于 WPF 使用保留模式系统,因此 OnRender() 不像旧的 WinAPI 时代那样工作。 OnRender() 只是存储了一组绘图指令,而 WPF 决定如何以及何时进行实际渲染。

    如果您需要更改控件的外观而不考虑大小,我建议您使用 DrawingVisual 之类的东西,并在您希望更改时使用 RenderOpen() 添加您的 mapDrawing。

    【讨论】:

    • 这正是我解决问题的方法,但有时我需要将这些 DrawingVisuals 扔给 UI。请在此处查看我的帖子stackoverflow.com/questions/8521789/…
    • 不确定为什么要转换为位图? DrawingVisual 是可见元素的最低级别。可见的一切都源自它,因此要在屏幕上显示一个,只需将其设置为 Window、Panel 或其他 ContentPresenter 的 Content 属性。
    • 我的地图不是静态的,图纸每秒变化 5 次,所以我认为在处理下一个视图时准备一个位图显示会很好
    • 我不是专家,但除非它成为性能问题,否则我会让 WPF 担心这一点。我会以 5Hz 的频率调用 RenderOpen()。
    • 这就是问题所在。绘制大量几何图形时,应用程序会变慢很多
    【解决方案2】:

    也许您可以使用地图绘制图像并将此图像设置为标准控件的源,而不是使用您自己的控件?像绘图这样的操作通常需要一些时间,所以最好在后台准备图像,然后切换到当前显示。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多