是否有一种简单的方法来确定控件的可见边界以优化渲染?

Posted

技术标签:

【中文标题】是否有一种简单的方法来确定控件的可见边界以优化渲染?【英文标题】:Is there an easy way to determine the visible bounds of a control to optimize rendering? 【发布时间】:2012-12-07 00:23:29 【问题描述】:

我们有一个非常大的子控件,它会进行大量渲染以显示其细节,但由于该控件只有一部分是实际可见的(它被层次结构更上层的东西剪裁,不一定是它的直接父控件),我们只想要在 OnRender 调用期间渲染可见部分。

考虑下图。孩子是 100x50,但可见区域是一个矩形,在孩子坐标中具有 (10,5) 和 (100,50) 的角。这就是我们正在寻找的区域。

注意:您不能简单地进行从子代到父代的坐标转换并测试剪裁,因为进行剪裁的可能不是父代。

考虑在 ScrollViewer 中嵌套 Canvas 控件。内层 Canvas 可能完全位于外层 Canvas 的边界内,但外层 Canvas 可能会被 ScrollViewer 剪切,因此内层 Canvas 在视觉上也会被它剪切。

遍历可视化树并测试每个父级会降低性能。

那么 WPF 中是否有内置的东西可以获取控件可见区域的边界?

【问题讨论】:

这个帖子可能会帮助你得到你想要的:***.com/questions/1517743/… 不!这只是边界检查(参见我上面的“注释”。)实际上并不代表可见的内容。 只是在黑暗中刺伤 - 使用反射器查看 IsMouseDirectlyOver 属性的内部结构(在大多数 WPF 控件上找到,可能从 FrameworkElement 继承)。该属性查看嵌套对象以确定鼠标是否直接位于确切的特定控件上。我在想你也许可以使用类似的逻辑进行边界检查...... 【参考方案1】:

我建议,一般来说,在您的 OnRender 方法中,您应该仔细注意它们的 Z 顺序来组合或渲染可见项目,但不必花时间担心可见的内容。这不是 C++。 WPF 设计背后的部分原因是系统应该能够为您决定什么是可见的,什么是不可见的。它旨在成为更高级别的抽象。如果你发现你正在编写代码来测试什么是可见的,以及那个可见部分的边界是什么——你可能没有正确使用它。是..有点懒惰。这(你上面描述的)应该很简单。

当您的可见对象四处滑动或以垂直顺序(即 Z 顺序)移动时,它们将变得可见或不可见。如果您希望某些东西在 Z 顺序中的位置不可见,那么您可以使其不可见(理想情况下,通过将其绑定到评估为 Visibility.Visible、Visibility.Hidden 或 Visibility.Collapsed 的属性)。

另请注意:在查看图形的各种实现时——尤其是对于从其他平台进入 WPF 的开发人员,我经常发现实际上没有必要重写 OnRender。除非您需要实时渲染大量图形,否则您通常可以让 WPF 为您完成工作,并且只需定义您想要在 XAML 中显示的内容。

【讨论】:

这些都是很好的观点,但它们并不适用。我们正在进行许多简单(甚至复杂)绑定无法处理的自定义渲染,因为它们可能在渲染实际发生之前包含数百次计算。但是它们的剪辑区域可能会根据其他因素而改变,因此我们花费了大量时间来渲染从未见过的东西。您实际上是在为不同的问题提出替代解决方案,而不是我的。我的问题是找到一种方法来确定裁剪区域。感谢您的意见。我相信它可以帮助其他人。只是不是我们。 为了记录,是的,我知道在 WPF 中,除非你正在处理说,OnRender 调用中的任何“渲染”根本不是真正的渲染,而是缓存绘图指令然后在实际调用渲染到硬件期间执行。对于这个问题,假设我们正在使用一个 WriteableBitmap,我们必须非常频繁地重新生成它的整体,所以如果某些东西实际上不可见,我们希望优化该部分。 好的,我明白了。这种类型的大多数 Q 来自对 WPF 相对较新或用于更简单场景的开发人员 - 显然不是这里的情况。我不知道通用的快捷方式。我已经完成了 2 个需要大量复杂渲染的操作:其中一个,内容是水平滑动(一组滚动的图形)。所以我使用 WritableBitmaps 以条带的形式进行概念性地组织,水平堆叠。当每个条带滑到左侧看不见时,它会被标记为屏幕外,反之亦然,因为条带在右侧进入视野。这完全取决于应用程序的几何性质

以上是关于是否有一种简单的方法来确定控件的可见边界以优化渲染?的主要内容,如果未能解决你的问题,请参考以下文章

在一组四叉树中找到最佳深度/范围以优化边界框中点的检索

确定组件是不是在 Flex 中完全可见的算法?

有没有办法确定 CSS 解析/渲染何时完成?

是否有一种方法可以绑定X:XAML中控件的参数?

OpenGL:如何在 3d 模式下优化多层相互重叠的 2d 渲染?

使对话框可见然后不可见