我想劫持通常的WPF渲染,以将控件拆分为基元,进行布局管理,为我应用绑定(bind)等。

据我了解,WPF中的整个渲染可以归结为在布局管理器计算的位置(具有依赖项属性系统定义的值)处渲染图元(文本,图像,线条,曲线)。如果我可以提供自己的图元渲染逻辑,则可以渲染例如转换为自定义文档类型,然后通过网络传输原语以进行真实渲染等。

我的计划如下:

  • 实现自定义 DrawingContext DrawingContext是一个抽象类,它定义了一堆方法,例如DrawEllipseDrawTextDrawImage等。我需要为此功能提供自己的实现。
  • 创建WPF UserControl并强制将其呈现为给定的DrawingContext

  • 但是,我遇到了以下问题:
  • DrawingContext包含抽象的内部方法void PushGuidelineY1(double coordinate)void PushGuidelineY2(double leadingCoordinate, double offsetToDrivenCoordinate),我不能轻易地覆盖它们。 (也许有一些技巧可以克服这个问题?)
  • 似乎没有方法可以在DrawingContext上呈现整个视觉效果?为什么?

  • 我可以做类似的事情
    void RenderRecursively(UIElement e, DrawingContext ctx)
    {
        e.OnRender(ctx);
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(e); i++)
            RenderRecursively((UIElement)VisualTreeHelper.GetChild(e, i), ctx);
    }
    

    -但我想知道是否存在直接呈现UIElement的方法。 (当然,这个问题是次要的问题,但是没有任何基础设施让我怀疑这是否是正确的方法。)

    那么,DrawingContext是否不打算从中继承?提供自定义DrawingContext的整个思路是朝着正确方向迈出了一步,还是我需要重新考虑策略?是使用WPF支持的自定义上下文,还是需要寻找其他拦截点?

    最佳答案

    您可能需要从相反的方向解决此问题。您可以要求WPF为您提供一个DrawingContext,而不是提供自己的Drawing。因此,它比您要使用的“推”方法更像是“拉”方法,但应该可以使它到达同一位置:如果您的Drawing可以完全表示零件的外观这是可视化树的一种数据结构,您可以步行并发现通过调用自定义DrawingContext会发现的所有内容。

    我相信这与XPS文件导出Sebastian提到的内部使用相同的基本方法。但是,直接使用它比通过XPS API使用它更直接。

    核心是相当简单的东西: VisualTreeHelper.GetDrawing 。这将返回DrawingGroup。 (Drawing是抽象基类。)该文档页面显示了如何遍历返回的树。不幸的是,这并不能完成全部工作:它只是为您碰巧调用它的任何节点提供视觉效果,并且如果该节点有子节点,则不会包含这些子节点。

    因此,不幸的是,您将仍然必须编写一些递归可视化树的内容,就像您已经在计划中一样。而且,您还需要处理任何不透明蒙版,不基于蒙版的不透明性,剪辑区域,效果和附加到视觉上的变换,以获得正确的结果;您还必须做所有的事情才能使您建议的方法正确地工作,所以这里什么都没有真正改变。 (按照Sebastian的建议使用XPS API的一个潜在优势是,它可以为您完成所有这些工作。但是,从XPS文档中以所需的形式提取信息是您的问题,这可能最终会丢失您所需要的信息。可能想要保留。)

    关于c# - 渲染到自定义的DrawingContext中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18193122/

    10-11 18:57