【发布时间】:2013-08-12 17:32:16
【问题描述】:
我想劫持通常的 WPF 渲染来将控件拆分为基元,进行布局管理,为我应用绑定等。
据我了解,WPF 中的整个渲染归结为在布局管理器计算的位置处渲染图元(文本、图像、线条、曲线),其值由依赖属性系统定义。如果我可以提供自己的原始渲染逻辑,我将能够渲染例如到自定义文档类型,传输原语以通过网络进行真实渲染等。
我的计划如下:
- 实现自定义
DrawingContext。DrawingContext是一个抽象类,它定义了一堆方法,如DrawEllipse、DrawText、DrawImage等。我需要为这个功能提供自己的实现。 - 创建一个 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 支持的自定义上下文上绘图,还是我需要寻找不同的拦截点?
【问题讨论】:
-
来自关于 DrawingContext 的评论:
You never directly instantiate a DrawingContext; you can, however, acquire a drawing context from certain methods, such as DrawingGroup.Open and DrawingVisual.RenderOpen.对我来说,这意味着无法在某处真正提供自定义 DrawingContext。 -
@Clemens:是的,我看到了这句话,但我理解为“您通常不应该自己创建它,我们会在内部为您完成;而要绘制到 DrawingVisual,只需让 DrawingVisual 正确初始化它”。无论如何,有趣的是是否有有效的绘图截取点。
-
绘制到 DrawingVisual 的唯一方法是绘制到 DrawingVisual.RenderOpen 提供的 DrawingContext。根本无法将您的自定义 DrawingContext 与 Visual 关联。这个想法毫无意义。
-
我认为您作为示例提供的实现是正确的路径。这是比您要求的更好的拦截点,因为您有能力检查您获得的孩子的类型并对其做出反应。如果您有一个事件只接收线、弧等原语。您的下一步可能是检查哪个父级是该原语...所以..是的,在我看来,您走在正确的道路上。跨度>
-
DrawingContext 及其所有派生类都没有公共构造函数,所以不,你不能从它派生。 WPF 不像 EMF 或 WMF,或者打印机驱动程序,或者说 Postscript。没有“原始”的概念。底层实现(媒体接口层“MIL”)完全不受管理且大部分未记录。
标签: c# wpf drawingcontext