How to get a screenshot of the whole treeview tree structure? I did this with the following code, but it only gets an image of the visible area of ​​the tree:

RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap((int)TreeElement.ActualWidth, (int)TreeElement.ActualHeight, 96, 96, PixelFormats.Pbgra32); renderTargetBitmap.Render(TreeElement); JpegBitmapEncoder jpegBitmapEncoder = new JpegBitmapEncoder { QualityLevel = 100 }; jpegBitmapEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap)); using (FileStream fileStream = new FileStream("Tree.jpg", FileMode.Create)) { jpegBitmapEncoder.Save(fileStream); fileStream.Close(); } 

enter image description here

    1 answer 1

    The problem is this.

    You get the right screenshot: your TreeView looks exactly like that . He has a ScrollViewer inside that limits visibility.

    There are several ways to solve the problem. The easiest one, probably, is to browse the children of our TreeView and find the ScrollViewer 's “inner part”.

    This is done like this:

     IEnumerable<FrameworkElement> GetChildren(FrameworkElement fe) { int nChildren = VisualTreeHelper.GetChildrenCount(fe); for (int i = 0; i < nChildren; i++) yield return (FrameworkElement)VisualTreeHelper.GetChild(fe, i); } IEnumerable<FrameworkElement> GetAllChildren(FrameworkElement fe) => new[] { fe }.Concat(GetChildren(fe).SelectMany(GetAllChildren)); 

    Or, if you are working with a new .NET 4.7.1, then

     IEnumerable<FrameworkElement> GetAllChildren(FrameworkElement fe) => GetChildren(fe).SelectMany(GetAllChildren).Prepend(fe); 

    Looking into the visual tree using the Live Visual Tree, we see that we need a child element of the ScrollContentPresenter type.

    We write:

     var presenter = GetAllChildren(TreeElement).OfType<ScrollContentPresenter>().First(); var content = (FrameworkElement)VisualTreeHelper.GetChild(presenter, 0); RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap((int)content .ActualWidth, (int)content .ActualHeight, 96, 96, PixelFormats.Pbgra32); renderTargetBitmap.Render(content); JpegBitmapEncoder jpegBitmapEncoder = new JpegBitmapEncoder { QualityLevel = 100 }; jpegBitmapEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap)); using (var fileStream = File.Create("Tree.jpg")) jpegBitmapEncoder.Save(fileStream); 

    Disadvantage: you do not get the background color, because the background is drawn above the visual tree. But you can already “put” the background on the picture, ok?