title: Quality of screenshot
body: <p>In one of my previous questions I asked how I could take a screenshot of everything  that's inside of a <code>ScrollViewer</code>, not just what's visible in the <code>ViewPort</code>. After a lot of trying I found myself an answer, but unfortunately this answer raises another question.</p>
  <p>Have a look at this example code:</p>
  <p>ItemViewModel.vb (just a simple view model for my <code>TreeViewItem</code>s):</p>
  <pre><code>Public Class ItemViewModel
      Public Property Text As String
      Public Property Items As New ObservableCollection(Of ItemViewModel)
  End Class
  </code></pre>
  <p>ViewModel.vb (the view model for my main window, creating some items in the constructor):</p>
  <pre><code>Public Class ViewModel
      Public Property Items As New ObservableCollection(Of ItemViewModel)
  
      Private Const levels As Integer = 3
  
      Public Sub New()
          Dim item1 As ItemViewModel
          Dim item2 As ItemViewModel
          Dim item3 As ItemViewModel
  
          For index1 As Integer = 1 To levels
              item1 = New ItemViewModel With {.Text = String.Format(&quot;Node {0} - {1}&quot;, index1, Guid.NewGuid.ToString)}
              Me.Items.Add(item1)
  
              For index2 As Integer = 1 To levels
                  item2 = New ItemViewModel With {.Text = String.Format(&quot;Node {0}.{1} - {2}&quot;, index1, index2, Guid.NewGuid.ToString)}
                  item1.Items.Add(item2)
  
                  For index3 As Integer = 1 To levels
                      item3 = New ItemViewModel With {.Text = String.Format(&quot;Node {0}.{1}.{2} - {3}&quot;, index1, index2, index3, Guid.NewGuid.ToString)}
                      item2.Items.Add(item3)
                  Next index3
              Next index2
          Next index1
      End Sub
  
  End Class
  </code></pre>
  <p>MainWindow.xaml (the main window itself, showing a <code>TreeView</code>):</p>
  <pre><code>&lt;Window x:Class=&quot;MainWindow&quot;
          xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
          xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
          xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
          xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
          xmlns:local=&quot;clr-namespace:ScreenshotTest&quot;
          mc:Ignorable=&quot;d&quot;
          Title=&quot;MainWindow&quot;
          Height=&quot;200&quot; Width=&quot;300&quot; KeyDown=&quot;Window_KeyDown&quot;&gt;
  
      &lt;Window.DataContext&gt;
          &lt;local:ViewModel /&gt;
      &lt;/Window.DataContext&gt;
  
      &lt;TreeView x:Name=&quot;Tree&quot; ItemsSource=&quot;{Binding Items}&quot;&gt;
          &lt;TreeView.ItemTemplate&gt;
              &lt;HierarchicalDataTemplate DataType=&quot;{x:Type local:ItemViewModel}&quot; ItemsSource=&quot;{Binding Items}&quot;&gt;
                  &lt;Border BorderThickness=&quot;1&quot; BorderBrush=&quot;Black&quot; Margin=&quot;1&quot;&gt;
                      &lt;TextBlock Text=&quot;{Binding Text}&quot; Margin=&quot;2&quot; /&gt;
                  &lt;/Border&gt;
              &lt;/HierarchicalDataTemplate&gt;
          &lt;/TreeView.ItemTemplate&gt;
          &lt;TreeView.ItemContainerStyle&gt;
              &lt;Style TargetType=&quot;{x:Type TreeViewItem}&quot;&gt;
                  &lt;Setter Property=&quot;IsExpanded&quot; Value=&quot;True&quot; /&gt;
              &lt;/Style&gt;
          &lt;/TreeView.ItemContainerStyle&gt;
      &lt;/TreeView&gt;
  &lt;/Window&gt;
  </code></pre>
  <p>MainWindow.xaml.vb (code-behind for the main window, here's where the &quot;useful&quot; code sits):</p>
  <pre><code>Class MainWindow
  
      Private Sub Window_KeyDown(sender As Object, e As KeyEventArgs)
          Dim panel As StackPanel
  
          If e.Key &lt;&gt; Key.P Then
              Exit Sub
          End If
  
          panel = GetFirstChildOfType(Of StackPanel)(Me.Tree)
          panel.Background = Brushes.White
          panel.UpdateLayout()
  
          Me.CaptureScreen(panel, &quot;C:\Temp\Screenshot.png&quot;)
      End Sub
  
      Private Shared Function GetFirstChildOfType(Of T As DependencyObject)(obj As DependencyObject) As T
          Dim result As T
          Dim child As DependencyObject
  
          If (obj Is Nothing) Then
              Return Nothing
          End If
  
          If (VisualTreeHelper.GetChildrenCount(obj) = 0) Then
              Return Nothing
          End If
  
          For index As Integer = 0 To VisualTreeHelper.GetChildrenCount(obj)
              child = VisualTreeHelper.GetChild(obj, index)
              result = TryCast(child, T)
  
              If (result Is Nothing) Then
                  result = GetFirstChildOfType(Of T)(child)
              End If
  
              If (result IsNot Nothing) Then
                  Return result
              End If
          Next index
  
          Return Nothing
      End Function
  
      Private Sub CaptureScreen(source As UIElement, filename As String)
          Dim height As Double
          Dim renderHeight As Double
          Dim width As Double
          Dim renderWidth As Double
          Dim renderTarget As RenderTargetBitmap
          Dim vb As VisualBrush
          Dim dv As DrawingVisual
          Dim encoder As PngBitmapEncoder
  
          Try
              height = source.RenderSize.Height
              renderHeight = height
              width = source.RenderSize.Width
              renderWidth = width
  
              renderTarget = New RenderTargetBitmap(Convert.ToInt32(renderWidth), Convert.ToInt32(renderHeight), 96, 96, PixelFormats.Pbgra32)
              vb = New VisualBrush(source)
  
              dv = New DrawingVisual
  
              Using dc As DrawingContext = dv.RenderOpen
                  dc.DrawRectangle(vb, Nothing, New Rect(New Point(0, 0), New Point(width, height)))
              End Using
  
              renderTarget.Render(dv)
  
              encoder = New PngBitmapEncoder
              encoder.Frames.Add(BitmapFrame.Create(renderTarget))
  
              Using fs As IO.FileStream = New IO.FileStream(filename, IO.FileMode.Create, IO.FileAccess.Write)
                  encoder.Save(fs)
              End Using
          Catch ex As Exception
              Stop
          End Try
      End Sub
  
  End Class
  </code></pre>
  <p>If you run this program, you'll see a <code>TreeView</code> with a few items, and if you press P a screenshot of the content of the <code>TreeView</code> is taken and saved as &quot;C:\Temp\Screenshot.png&quot;.</p>
  <p>So far, so good, the screenshot roughly looks like what's seen on screen (quality-wise). If you view the created png file for instance in IrfanView (at 100% size), everything is readable.</p>
  <p>But if I create more and more items (increasing the <code>levels</code> constant to 5 and then to 7), the quality of the picture is getting worse, at <code>levels</code>=7 one can't read anything on the screenshot.</p>
  <p>Does anyone know what is happening here and how I could fix that? I'm fine with answers in C# as well.</p>
  <p>Here's a few screenshots to visualize my problem:</p>
  <p>Main window on screen</p>
  <p><a href="https://i.stack.imgur.com/JOQI1.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/JOQI1.png" alt="Main window on screen" /></a></p>
  <p>Screenshot with levels=3</p>
  <p><a href="https://i.stack.imgur.com/zPmpd.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/zPmpd.png" alt="Screenshot with levels=3" /></a></p>
  <p>Screenshot with levels=5</p>
  <p><a href="https://i.stack.imgur.com/4nYA9.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/4nYA9.png" alt="Screenshot with levels=5" /></a></p>
  <p>Screenshot with levels=7</p>
  <p><a href="https://i.stack.imgur.com/NSrZ4.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/NSrZ4.png" alt="Screenshot with levels=7" /></a></p>