You may need to approach this problem from the opposite direction. Instead of aiming to provide your own DrawingContext
, you can instead ask WPF to provide you with a Drawing
. So it's more of a 'pull' approach' than the 'push' approach you're aiming for, but it should make it possible to get to the same place: if you have a Drawing
that is a complete representation of the appearance of part of the visual tree, that's a data structure you can walk and discover everything that you would have discovered from calls to a custom DrawingContext
.
I believe this is the same basic approach that the XPS document export Sebastian mentions uses internally. But using it directly yourself is a more direct approach than using it through the XPS APIs
At the heart is something fairly simple: VisualTreeHelper.GetDrawing
. This returns a DrawingGroup
. (Drawing
is an abstract base class.) That documentation page shows you how to walk through the tree that you get back. Unfortunately, this doesn't do the whole job: it just provides the visuals for whichever node you happen to call it in, and if that node has children, they won't be included.
So you will, unfortunately, still have to write something that recurses the visual tree, much like you were already planning. And you will also need to handle any opacity masks, non-mask-based opacity, clip regions, effects, and transformations that are attached to the visual to get the correct results; you'd have had to do all that too to make your proposed approach work correctly, so nothing really changes here. (One potential advantage of using the XPS API as Sebastian suggests is that it does all this for you. However, it's then your problem to extract the information from the XPS document in the form you want, and that may end up losing information that you might want to preserve.)