我试图弄清楚 WPF 渲染系统是如何工作的,现在我被困住了几天来有问题:
视觉如何将绘图对象列表交付到渲染系统?
我没有看到Visual的成员服务于此目的。
简而言之,我必须在以下方面实现:
public class MyVisual : Visual
{
// ???
}
因此
DrawingGroup dg = VisualTreeHelper.GetDrawing( new MyVisual() );
变为非空(有效的绘图组对象(?
编辑(2013年3月14日(:
我希望这个问题对于任何有以下情况的人来说都应该很容易回答了解 WPF,但看起来并非如此。
一个多星期前我问过这个问题,这个非常具体、具体、尽管没有回答有关WPF体系结构的基本问题周围有这么多WPF专家。有没有可能没有人那些回答了这么多"上层"问题的 WPF 专家,实际上不知道 WPF 在基础级别是如何工作的?
实际上,我的问题是:是否有任何真正的WPF专家,或者它是如此神秘,超出了人类的理解?
为了使DrawingGroup dg = VisualTreeHelper.GetDrawing( new MyVisual() );
正常工作,您需要覆盖Visual.GetDrawing
。但是,这是一种internal virtual
方法,因此无法覆盖它。
我不认为直接从Visual
派生是一个受支持的场景;你应该从UIElement
派生或使用(通过组合或继承(其他Visual
派生类之一,例如DrawingVisual
(它公开了一个公共RenderOpen
方法(。
正如 Bradley 所提到的,你应该从 DrawingVisual
派生,而不是Visual
来完成这项工作。
你是在倒退。 Visual
是空的,直到您在其中渲染某些内容。 有些东西可以是一个空的DrawingGroup
...
获取与Visual
内容对应的DrawingGroup
DrawingGroup dg = new DrawingGroup();
using (DrawingContext myContext = myVisual.RenderOpen())
myContext.DrawDrawing(dg);
在RenderOpen
和处置DrawingContext
之间发生的一切都进入一个DrawingGroup
,Visual
内部存储。
然后
VisualTreeHelper.GetDrawing( myVisual )
将是一个非空DrawingGroup
(我还没有检查它是上面创建的那个,还是 WPF 创建的DrawingGroup
里面有一个项目,上面创建的那个(。
如果你想让VisualTreeHelper.GetDrawing( new MyVisual() )
工作,你只需要在MyVisual
的构造函数中执行上述操作:
MyVisual()
{
using (DrawingContext myContext = RenderOpen())
myContext.DrawDrawing(new DrawingGroup());
}
这样,GetDrawing
使用的内部数据结构已正确设置。 无需覆盖它。
[回答菲尔:那很好,除了Visual没有方法OnRender。你实际上是在谈论UIElement。
如果有人可以确认MSDN的这一行不正确,我将感到满意:
"视觉对象支持:[除其他外]- 输出显示:呈现视觉对象的持久化序列化绘图内容..."。
由于 UIElement、ContainerVisual 或 Viewport3DVisual 都有不同的绘图内容交付机制,这意味着视觉本身没有一个中心(多态(绘图交付机制,但这些角色落在这三个预定义的类上(换句话说,你不能创建不是从这三个类之一派生的新类型的视觉对象,因为渲染系统将无法呈现它,因为它只知道如何来处理这三个类,但不是视觉本身(。
我说的对吗?
编辑:
不可以。这个结论是不正确的,因为它们完全基于MICROSOFT文档中的内容。视觉对象比文档中的内容更多。要挖掘更多使用反射。