I don’t know if you have ever had the need to save an image of a Xaml/Wpf control but I did recently in a project. The method I have below will do just this:
public List<Bitmap> ExportToPng(List<object> objects) {
var images = new List<Bitmap>();
// iterate wpf objects, saving current canvas transform
foreach (object o in objects) {
Transform transform = c.LayoutTransform;
// reset current transform (in case it is scaled or rotated)
c.LayoutTransform = null;
// Create a render bitmap and push the surface to it
var renderBitmap =
new RenderTargetBitmap(
(int)c.ActualWidth,
(int)c.ActualHeight,
96d,
96d,
PixelFormats.Pbgra32);
renderBitmap.Render(c);
System.Drawing.Image ImageWork;
// Create a memory stream for using image
using (var stm = new MemoryStream()) {
// Use png encoder for our data
var encoder = new PngBitmapEncoder();
// push the rendered bitmap to it
encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
// save the data to the stream
encoder.Save(stm);
ImageWork = System.Drawing.Image.FromStream(stm);
images.Add(ImageWork as Bitmap);
}
// Restore previously saved layout
c.LayoutTransform = transform;
}
return images;
}
The method does take an array of objects, of course you could modify it to only do one at a time but I had several I needed in my example. The key thing here is that in your xaml code, make sure you have your control in just a single stackpanel, or a stackpanel per control. I found that when I had several controls in a single stackpanel, it was only grabbing the first one, the rest of the controls were not getting generated. This would be a really nice feature that Microsoft could provide to all their controls because I know I am not the only person that has wanted this functionality but had to write this hack in get it accomplished.


