-1

我试图弄清楚 WPF 渲染系统是如何工作的,现在我被困了好几天的问题:

Visual 如何将它的绘图对象列表传递给渲染系统?

我没有看到 Visual 的成员为此目的服务。

简而言之,我必须在以下方面实施:

public class MyVisual : Visual
{
   // ???
}

以便

DrawingGroup dg = VisualTreeHelper.GetDrawing( new MyVisual() );

变为非空(有效的 DrawingGroup 对象)?

编辑(2013 年 3 月 14 日):

我希望对于任何了解 WPF 的人来说,这个问题都应该很容易回答,但看起来并非如此。

一个多星期前我问了这个问题,尽管周围有这么多 WPF 专家,但这个关于 WPF 架构的非常具体、具体和基本的问题仍未得到解答。那些回答了这么多“上层”问题的 WPF 专家中没有一个人实际上不知道 WPF 在它的基础级别上是如何工作的吗?

实际上,我的问题实际上是:有没有真正的 WPF 专家,或者它是否如此神秘以至于超出了人类的理解?

4

3 回答 3

1

为了DrawingGroup dg = VisualTreeHelper.GetDrawing( new MyVisual() );工作,您需要覆盖Visual.GetDrawing. 但是,这是一种internal virtual方法,因此您不能覆盖它。

我不认为直接派生Visual是受支持的方案。您应该从UIElement其他派生类之一派生或使用(通过组合或继承)Visual,例如DrawingVisual(公开一个公共RenderOpen方法)。

于 2013-03-18T17:30:59.907 回答
1

正如布拉德利所提到的,你应该从而DrawingVisual不是Visual为了完成这项工作。


你倒着做。在Visual您将某些内容渲染到其中之前,它是空的。那东西可以是空的DrawingGroup...

得到一个DrawingGroup对应a的内容Visual

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已正确设置。无需覆盖它。

于 2014-06-12T21:47:31.667 回答
0

[对 Phil 的回答:这很好,只是 Visual 没有方法 OnRender。您实际上是在谈论 UIElement。]

如果有人能确认 MSDN 中的这条线是不正确的,我会很满意:

“Visual 对象提供以下支持:[除其他外] - 输出显示:呈现视觉对象的持久化、序列化绘图内容......”。

由于 UIElement、ContainerVisual 或 Viewport3DVisual 都有不同的绘图内容传递机制,那么这意味着 Visual 本身没有一个中心(多态的)绘图传递机制,但这些角色属于这三个预定义的类(换句话说,您不能创建不是从这三个类之一派生的新类型的 Visual,因为渲染系统将无法渲染它,因为它只知道如何处理这三个类,但不知道 Visual 本身)。

我对吗 ?

编辑:

不。此结论不正确,因为它们仅基于 MICROSOFT 文档中提供的内容。视觉对象比文档中的内容更多。挖掘更多使用反射。

于 2013-03-16T16:05:13.423 回答