自定义WPF控件会覆盖OnRender。该方法从自定义数据生成并显示路径。数据提供程序使用依赖项属性绑定。当数据发生变化时,依赖属性会为事件注册。此事件又调用InvalidateVisual()。
但是,在InvalidateVisual()之后,并不总是调用OnRender。
我们使用Prism Framework和Region functionallity。所讨论的控件嵌入在这样的区域中,该区域被激活和停用。但是,只要区域处于活动状态,Control的属性“IsVisible”就为true。但是,当调用InvalidateVisual()时,OnRender方法不会被调用...
什么可以阻止调用OnRender方法?
答案 0 :(得分:2)
我也遇到了这个问题。
我有一堆基于VirtualizingStackPanel(在ListBox内)的DynamicDataDisplay图形组件的控件。
如果有更多的控件一次可见,但不足以让VirtualizingStackPanel在滚动时开始重新使用它们,那么我会看到D3 AxisControl类的这个问题。由于某种原因,它在OnRender方法中做了很多工作,它试图通过在某些内容发生变化时调用InvalidateVisual来触发。
在问题情况下,问题控件调用InvalidateVisual,但他们永远不会调用MeasureOverride,ArrangeOverride 或 OnRender。有趣的是,大多数控件仍然有效,在一个特定的问题情况下,我得到一组11中的最后3个无法正常工作。值得注意的是,那些3(并且只有那3个)在触发对InvalidateVisual的调用的数据绑定更新之前立即接收到对MeasureOverride的调用。
最后,我设法通过添加对InvalidateMeasure的调用以及对InvalidateVisual的调用来修复它。
这是一个可怕的解决方案,但它不是我们应用程序的性能关键部分,所以我似乎正在逃避它。
答案 1 :(得分:0)
如果您的控件的大小保持不变,则不应使用 <select id="menu">
<option>Choose a Day</option>
<option id="snd">Sunday</option>
<option>Monday</option>
<option>Tuesday</option>
<option>Wednesday</option>
<option>Thursday</option>
<option>Friday</option>
<option id="strd">Saturday</option>
</select>
或InvalidateMeasure()
,因为它们会触发昂贵的重新布局。
WPF是保留的绘图系统。 InvalidateVisual()
可能更好地称为OnRender()
,因为它实际上并没有绘制。它累积了一组绘图对象,WPF用它来随时绘制UI。奇怪的是,如果您在AccumulateDrawingObjects()
期间将DrawingGroup
放入DrawingContext
,您实际上可以在 OnRender()
之后有效地更新 {喜欢。
有关详细信息,请参阅我的答案..
答案 2 :(得分:-1)
我也遇到了这个问题。
我有一个控件滚动条,它只在 class SelectableItemWidget extends StatefulWidget {
..
....
...
class _SelectableItemWidgetState extends State<SelectableItemWidget> {
...
....
Widget build(BuildContext context) {
return Consumer<ItemProvider>(builder: (context, itemprovider, child) {
....
onTap: () => itemprovider.increase(widget.index),
期间计算出显示所有内容真正需要多少空间,这可能比可用显示空间大,因此需要一个滚动条。 OnRender()
可能会调用一些方法,这些方法最终改变了本来应该以 OnRender()
开始 OnRender()
的滚动条的值。
然而,在 InvalidateVisual()
之后没有再次调用 OnRender()
。我想原因是 InvalidateVisual()
设置了一些标志,告诉 WPF 控件需要再次绘制,但是一旦 InvalidateVisual()
完成,该标志就会重置。这里有一些我期望它发生的伪代码:
OnRender()
我没有进一步调查 WPF 是否真的以这种方式工作,但它可以解释为什么 //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;
}
不会被第二次调用。
我没有浪费更多的时间,而是改变了计算控件内容总宽度的方法,并将这段代码放在OnRender()
之外。