I'd like to hijack the usual WPF rendering to split the controls into primitives, do the layout management, apply the bindings etc. for me.
As far as I understand, the whole rendering in WPF boils down to rendering of primitives (text, image, line, curve) at the locations calculated by the layout manager with values defined by the dependency property system. If I could supply my own primitive-rendering logic, I would be able to render e.g. to a custom document type, transfer the primitives for real rendering over the network etc.
My plan is following:
- Implement a custom
DrawingContext
. TheDrawingContext
is an abstract class, which defines a bunch of methods likeDrawEllipse
,DrawText
,DrawImage
etc. — I'll need to supply my own implementation for this functionality. - Create a WPF
UserControl
and force it to render into a givenDrawingContext
.
However I've encountered the following problems:
DrawingContext
contains abstract internal methodsvoid PushGuidelineY1(double coordinate)
andvoid PushGuidelineY2(double leadingCoordinate, double offsetToDrivenCoordinate)
, which I cannot override easily. (Perhaps there is some trick to overcome this?)- There seems to be no method to render the whole visual on a
DrawingContext
? Why?
I can do something like
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);
}
— but I wonder if there is a direct way to render an UIElement
. (Of course, this problem is a minor one, but seeing no infrastructure for it makes me wonder if this is the proper way.)
So, is the DrawingContext
not intended for inheriting from? Is the whole idea of supplying a custom DrawingContext
a step in the right direction, or I need to rethink the strategy? Is drawing onto a custom context supported in WPF, or I need to look for a different interception point?
You never directly instantiate a DrawingContext; you can, however, acquire a drawing context from certain methods, such as DrawingGroup.Open and DrawingVisual.RenderOpen.
To me this means that there is no way to actually supply a custom DrawingContext somewhere. – Elkins