首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在InvalidateVisual()之后未调用OnRender

在InvalidateVisual()之后未调用OnRender
EN

Stack Overflow用户
提问于 2013-06-10 18:46:59
回答 3查看 3.9K关注 0票数 9

自定义WPF控件重写OnRender。该方法从自定义数据生成并显示路径。数据提供程序是使用依赖属性绑定的。当数据更改时,Dependency属性注册事件。该事件依次调用InvalidateVisual()。

但是,在InvalidateVisual()之后,并不总是调用OnRender。

我们使用棱镜框架和区域功能。有问题的控件嵌入在这样的区域中,该区域处于激活和停用状态。但是,只要区域处于活动状态,控件的属性"IsVisible“就为true。但是,在调用InvalidateVisual()时,不会调用OnRender方法...

什么可以阻止OnRender方法被调用?

EN

回答 3

Stack Overflow用户

发布于 2013-10-14 15:41:40

我也遇到了这个问题。

上下文

我在VirtualizingStackPanel中(在ListBox中)获得了大量基于DynamicDataDisplay图形组件的控件。

当有更多的控件同时可见,但不足以让VirtualizingStackPanel在滚动时开始重用它们时,我发现D3 AxisControl类存在这个问题。由于某些原因,它在它的OnRender方法中做了很多工作,当某些事情发生变化时,它试图通过调用InvalidateVisual来触发该方法。

在出现问题的情况下,问题控件调用InvalidateVisual,但从未调用过MeasureOverride、ArrangeOverride或OnRender。有趣的是,大多数控件仍然可以正常工作,在一个特定的问题案例中,我得到了11个无法正常工作的集合中的最后3个。值得注意的是,在触发对InvalidateVisual的调用的数据绑定更新之前,这3个(并且只有这3个)接收到对MeasureOverride的调用。

我的解决方案

最后,我设法修复了它,在调用InvalidateVisual的同时添加了一个对InvalidateMeasure的调用。

这是一个可怕的解决方案,但它不是我们的应用程序的性能关键部分,所以我似乎没有受到影响。

票数 2
EN

Stack Overflow用户

发布于 2017-06-10 15:02:38

如果控件的大小保持不变,则不应使用InvalidateMeasure()InvalidateVisual(),因为它们会触发昂贵的重新布局。

WPF是一种保留绘图系统。将OnRender()命名为AccumulateDrawingObjects()可能更好,因为它实际上并不绘制。它累积了一组绘图对象,WPF可以随时使用这些对象来绘制您的UI。神奇的是,如果您在OnRender()期间将一个DrawingGroup放入DrawingContext中,您实际上可以在OnRender之后随时高效地更新它。

有关更多详细信息,请参阅我的答案。

https://stackoverflow.com/a/44426783/519568

票数 0
EN

Stack Overflow用户

发布于 2021-07-30 03:34:46

我也遇到了这个问题。

我有一个控件的滚动条,它只在OnRender()期间计算出显示所有内容真正需要多少空间,这可能比可用显示空间大,因此需要一个滚动条。可能发生的情况是,OnRender()调用了一些方法,这些方法最终改变了scrollbar的值,而scrollbar应该用InvalidateVisual()启动OnRender()

但是,在InvalidateVisual()之后,没有再次调用OnRender()。我猜原因是InvalidateVisual()设置了一些标志,告诉WPF控件需要重新绘制,但一旦OnRender()完成,该标志就会被重置。下面是我所期望的一些伪代码:

代码语言:javascript
复制
//someCode:
  control.InvalidateVisual()
    //code of InvalidateVisual()
    control.RedrawFlag = true;

//WPF some time later:
  if (control.RedrawFlag){
    control.OnRender()
      //OnRender code
      //do some stuff
      //decide control needs to be redrawn
      //however, RedrawFlag  is alreday true!
      //next line is not changing anything
      control.RedrawFlag = true; 

    //WPF finished executing control.OnRender
    control.RedrawFlag = false;
  }

我没有进一步调查WPF是否真的以这种方式工作,但这可以解释为什么OnRender()不会被第二次调用。

我没有浪费更多的时间,而是更改了如何计算控件内容的总宽度,并将此代码放在OnRender()之外。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17022078

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档