在 InvalidateVisual() 之后未调用 OnRender



>自定义 WPF 控件覆盖 OnRender。该方法从自定义数据生成并显示路径。数据提供程序使用依赖项属性绑定。依赖项属性在数据更改时注册事件。此事件依次调用 InvalidateVisual((。

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

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

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

我也有这个问题。

上下文

我有一个基于VirtualizingStackPanel(在ListBox内(中的DynamicDataDisplay图形组件的控件负载。

当同时可以看到更多控件,但不足以让 VirtualizingStackPanel 在您滚动时开始重用它们时,我在 D3 AxisControl 类中看到此问题。出于某种原因,它在OnRender方法中做了很多工作,当某些内容发生变化时,它试图通过调用InvalidateVisual来触发该方法。

在问题情况下,问题控件调用 InvalidateVisual,但它们从未收到对 MeasureOverride、ArrangeOverride OnRender 的调用。有趣的是,大多数控件仍然有效,在一个特定问题的情况下,我得到一组 11 个控件中的最后 3 个无法正常工作。值得注意的是,这 3 个(并且只有这 3 个(在触发对 InvalidateVisual 调用的数据绑定更新之前立即收到对 MeasureOverride 的调用。

我的修复

最后,我设法通过添加对InvalidateMeasure的调用以及对InvalidateVisual的调用来修复它。

这是一个可怕的解决方案,但它不是我们应用程序的性能关键部分,所以我似乎侥幸逃脱了。

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

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

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

这里..

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

我刚刚也遇到了这个问题。

我有一个用于控件的滚动条,它仅在OnRender()期间才能弄清楚显示所有内容真正需要多少空间,这可能大于可用的显示空间,因此需要一个滚动条。可能会发生OnRender()调用一些方法,这些方法最终改变了应该以InvalidateVisual()开头的滚动条的值OnRender()

但是,OnRender()InvalidateVisual()后没有再次接到电话。我想原因是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()之外。

相关内容

  • 没有找到相关文章

最新更新