I have a UIElement
that I want to capture a snapshot of when a user clicks a button. When a user clicks the button, I want to take the UIElement
and load it's current state into an Image element. How do I render a UIElement
as an Image
?

- 3,741
- 12
- 49
- 72

- 10,869
- 26
- 73
- 86
4 Answers
Assuming the FrameworkElement
you want to render is named elementToRender and the Image
where you want to place the rendered output is called image, use the following code on your button's click handler:
var writeableBitmap = new WriteableBitmap((int)elementToRender.RenderSize.Width, (int)elementToRender.RenderSize.Height);
writeableBitmap.Render(elementToRender, new ScaleTransform() { ScaleX = 1, ScaleY = 1 });
writeableBitmap.Invalidate();
image.Source = writeableBitmap;

- 3,741
- 12
- 49
- 72

- 884
- 1
- 7
- 18
-
This is a great solution, and I have used it in one of my projects. However, this seems to be rendering the bitmap of the element as it appears, including scrollbars if the element is, say, a large RichTextBox. Do you know if it is possible to render the whole element in such cases? – Artyom Feb 09 '12 at 08:48
-
No, I don't think it is possible. The rendering just acts on the visible part of the rendered element. – Bruno Feb 09 '12 at 21:38
You can also do the following:
private void SetImageSourceBasedOnElement(Image image, UIElement element)
{
if (element != null)
{
WriteableBitmap writableBitmap = new WriteableBitmap(element, null);
writableBitmap.Invalidate();
image.Source = writableBitmap;
}
}
WriteableBitmap wb = new WriteableBitmap(UIElement, new ScaleTransform() { ScaleX = 1, ScaleY = 1 });
wb.Invalidate();
Image.Source = wb;

- 1,052
- 1
- 8
- 19
-
I don't see how that link helps... He's asking about UIElement, not an image stream. – Pat Niemeyer Mar 21 '11 at 21:35
-
Ultimately, no, you cannot render an entire UIElement
, including the parts that aren't visible due to scrolling overflow, etc.
I looked into how you could get around this using reflection. Unfortunately, you cannot override how UIElement
renders, as it is just a light wrapper for the internal class XcpImports, which in turn is a wrapper for various native methods used throughout Silverlight. In other words, UIElement
and how it is rendered is completely native, and thus there is no (easy) way to override how it displays using reflection.
If you wanted to take the hackish approach, you could enclose your element in a Grid, remove it from that grid, put it in another grid that is the same size as the element--see where I'm going with this? But that would be quite a hassle, and hackish at best.

- 3,741
- 12
- 49
- 72

- 18,788
- 9
- 71
- 77