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.