题
我无法理解何时调用 OnRender 方法。考虑我的例子:我有一个继承自 FrameworkElement 的 SomeElement 类,它重写了 OnRender 方法。假设我有一个 Grid grid
. 。我所期望的是
var someElement = new SomeElement();
grid.AddVisualChild(someElement);
someElement.InvalidateVisual();
会导致 SomeElement.OnRender 方法被触发。我的情况并非如此,但以下内容确实如此:
var someElement = new SomeElement();
grid.Children.Add(new SomeElement());
someElement.InvalidateVisual();
所以我的问题是为什么 someElement
仅添加到可视化树时不会绘制。将其添加到属性中有何重要性 Children
?更一般地说,OnRender 是如何调用的?通过视觉树,或者 Children
财产,或者?
解决方案
AddVisualChild 并没有做您可能认为的事情。
AddVisualChild 只是用于在 VisualTree 中的两个视觉对象之间创建子父关系。没什么更多或更少。VisualTree 不会渲染其中的所有内容。
AddLogicalChild 执行相同的操作,只是创建 LogicalTree。LogicalTree 通常比 VisualTree 更小、更短,这意味着它更快。
为了完全支持您的孩子的渲染,您需要对他们调用measure方法和arrange方法。此外,您需要更改父级的 VisualChildrenCount 属性,并将正确的大小传递给每个子级,并且需要将它们放置在正确的位置以便用户能够看到它们。然后事情就会被渲染。
单独调用 AddVisualChild 和 InvalidateVisual 没有执行任何操作。
另一方面,Children 集合是一个 UIElementCollection,它会自动执行我提到的所有上述操作。这就是它与 Children.Add(...) 一起使用的原因。
此外,您应该始终使用 Children 集合,而不是编写自己的东西。
就像 HighCore 提到的,许多问题只需拥有一个合适的 MVVM 就可以解决。
也许您不需要自定义控件。