title: UI caching with ItemsControl
body: <p>I have a performance problem in my WPF application. (I guess that's not a new thing...) Basically the application contains of a <code>ListBox</code> with items that can be selected, and a <code>ContentControl</code> that shows details for the selected item. For one type of item, there's an <code>ItemsControl</code> involved that displays a list of subitems. And this is the problem. As soon as I remove that <code>ItemsControl</code>, or only have it display a very small number of subitems (&lt; 3), it's fast. But with 50 subitems, browsing through the list feels way too slow.</p>
  
  <p>You'd probably suggest me some sort of virtualisation, but that doesn't apply here. In many cases, all items will fit on the screen, so they need to be displayed immediately anyway. No need to virtualise items that are out of sight.</p>
  
  <p>I could strip down my whole application to just a few short classes (views and view models) that demonstrate the performance issue. This test case can be <a href="http://unclassified.de/tmp/FieldLog-perftest.zip" rel="nofollow noreferrer">downloaded here</a>. Just run the application, select an item from the list on the left side and move to other items by pressing and holding the up or down arrow keys. Normally, this shows the other item instantly, but here it takes a very noticeable time of ~160 ms each.</p>
  
  <p>The core of the view looks like this:</p>
  
  <pre><code>&lt;UserControl ...&gt;
    &lt;ScrollViewer VerticalScrollBarVisibility="Auto"&gt;
      &lt;ItemsControl ItemsSource="{Binding StackFrameVMs, Mode=OneTime}"&gt;
        &lt;ItemsControl.ItemTemplate&gt;
          &lt;DataTemplate&gt;
            &lt;StackPanel Orientation="Horizontal"&gt;
              &lt;TextBlock Text="•" Foreground="{Binding ...}"/&gt;
              &lt;TextBox Margin="4,0,0,0" Text="{Binding ...}"/&gt;
              &lt;TextBox Margin="12,0,0,0" Text="{Binding ...}"/&gt;
            &lt;/StackPanel&gt;
          &lt;/DataTemplate&gt;
        &lt;/ItemsControl.ItemTemplate&gt;
      &lt;/ItemsControl&gt;
    &lt;/ScrollViewer&gt;
  &lt;/UserControl&gt;
  </code></pre>
  
  <p>That's not a lot of UI controls, but I need them all. Actually there's a few more controls and bindings in my real application, but these are sufficient for the demo. When I move the contents of the <code>DataTemplate</code> to a separate <code>UserControl</code> and insert that instead, it takes even longer.</p>
  
  <p>From previous profilings I believe that <code>ItemsControl</code> throws away and recreates all controls for the list items every time the list changes, because a different item is selected (and <code>DataContext</code> of the details view changes). Even if the view itself is reused because the new selected item has the same type and uses the same <code>DataTemplate</code>.</p>
  
  <p>Is there a way to make <code>ItemsControl</code> reuse the items it has once created? Maybe even all of them, if one of the selected items needs fewer but the next needs more again? Or is there any way to improve the performance for this very simple use case in another way?</p>
  
  <p><strong>Update:</strong> BTW, note that this example code is a very much stripped down version of what my full application looks like. You might think you could simplify the structure I chose, but consider that the full application looks something like the following screenshot. There's more than just the <code>ItemsControl</code>, and there are different detail views for different item types selectable from the left list. So I basically need the structure I have, it just needs to be faster.</p>
  
  <p><img src="https://i.stack.imgur.com/z0kj9.png" alt="Screenshot"></p>
  
  <p>The whole project is open source, you may take a look at the complete solution if you like: <a href="https://github.com/dg9ngf/FieldLog" rel="nofollow noreferrer">https://github.com/dg9ngf/FieldLog</a></p>