自定义WPF控件重写OnRender。该方法从自定义数据生成并显示路径。数据提供程序是使用依赖属性绑定的。当数据更改时,Dependency属性注册事件。该事件依次调用InvalidateVisual()。
但是,在InvalidateVisual()之后,并不总是调用OnRender。
我们使用棱镜框架和区域功能。有问题的控件嵌入在这样的区域中,该区域处于激活和停用状态。但是,只要区域处于活动状态,控件的属性"IsVisible“就为true。但是,在调用InvalidateVisual()时,不会调用OnRender方法...
什么可以阻止OnRender方法被调用?
发布于 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的调用。
这是一个可怕的解决方案,但它不是我们的应用程序的性能关键部分,所以我似乎没有受到影响。
发布于 2017-06-10 15:02:38
如果控件的大小保持不变,则不应使用InvalidateMeasure()或InvalidateVisual(),因为它们会触发昂贵的重新布局。
WPF是一种保留绘图系统。将OnRender()命名为AccumulateDrawingObjects()可能更好,因为它实际上并不绘制。它累积了一组绘图对象,WPF可以随时使用这些对象来绘制您的UI。神奇的是,如果您在OnRender()期间将一个DrawingGroup放入DrawingContext中,您实际上可以在OnRender之后随时高效地更新它。
有关更多详细信息,请参阅我的答案。
发布于 2021-07-30 03:34:46
我也遇到了这个问题。
我有一个控件的滚动条,它只在OnRender()期间计算出显示所有内容真正需要多少空间,这可能比可用显示空间大,因此需要一个滚动条。可能发生的情况是,OnRender()调用了一些方法,这些方法最终改变了scrollbar的值,而scrollbar应该用InvalidateVisual()启动OnRender()。
但是,在InvalidateVisual()之后,没有再次调用OnRender()。我猜原因是InvalidateVisual()设置了一些标志,告诉WPF控件需要重新绘制,但一旦OnRender()完成,该标志就会被重置。下面是我所期望的一些伪代码:
//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()之外。
https://stackoverflow.com/questions/17022078
复制相似问题