title: ListView items from an ObservableCollection that need to prepare themselves for realization
body: <p>I have a ListView which is supposed to display a rather large number of items comprised of a "Name", a "Thumbnail" and a "AnimationPosition" property. A background task in each item's type is in charge of switching the thumbnails in order to animate them.</p>
  
  <p>Now it goes without saying that this is a rather heavy operation and should be limited to as few items as possible e.g. to visible/realizing items of a Virtualized ListView. Now I already have set the DataContext of my ListView to the ObeservableCollection instance and have bound it to the properties of its type. Here's a peek into my XAML code for that.</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;TabControl Grid.Row="0" Grid.Column="2"&gt;
  
    &lt;TabControl.Resources&gt;
  
      &lt;Style x:Key="MediaItemStyle" TargetType="{x:Type ListViewItem}"&gt;
  
        &lt;Setter Property="Margin" Value="5,5,5,5"/&gt;
        &lt;Setter Property="Padding" Value="0,0,0,0"/&gt;
        &lt;Setter Property="HorizontalAlignment" Value="Left"/&gt;
        &lt;Setter Property="Template"&gt;
          &lt;Setter.Value&gt;
            &lt;ControlTemplate  TargetType="{x:Type ListViewItem}"&gt;
              &lt;Grid HorizontalAlignment="Left" VerticalAlignment="Top" Height="Auto" &gt;
                &lt;Border x:Name="border" BorderBrush="{x:Null}" BorderThickness="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" CornerRadius="2.5"/&gt;
                &lt;StackPanel HorizontalAlignment="Stretch"  VerticalAlignment="Stretch"&gt;
                  &lt;ContentPresenter/&gt;
                &lt;/StackPanel&gt;
              &lt;/Grid&gt;
            &lt;/ControlTemplate&gt;
          &lt;/Setter.Value&gt;
        &lt;/Setter&gt;
  
      &lt;/Style&gt;
  
      &lt;Style TargetType="custom:MediaContainerListView"&gt;
  
        &lt;Setter Property="ItemsSource" Value="{Binding}"/&gt;
        &lt;Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/&gt;
        &lt;Setter Property="ItemContainerStyle" Value="{StaticResource MediaItemStyle}"/&gt;
        &lt;Setter Property="ItemsPanel"&gt;
          &lt;Setter.Value&gt;
            &lt;ItemsPanelTemplate&gt;
              &lt;WrapPanel/&gt;
            &lt;/ItemsPanelTemplate&gt;
          &lt;/Setter.Value&gt;
        &lt;/Setter&gt;
        &lt;Setter Property="ItemTemplate"&gt;
          &lt;Setter.Value&gt;
            &lt;DataTemplate&gt;
              &lt;DockPanel Width="256"&gt;
  
                &lt;Image DockPanel.Dock="Top" Height="144" StretchDirection="Both" 
                       Stretch="Fill" Source="{Binding Thumbnail.Source,Mode=OneWay}"/&gt;
  
                &lt;ProgressBar DockPanel.Dock="Top" Height="2"
                             Minimum="0" Maximum="{Binding Thumbnail.AnimationPosition.Length}"
                             Value="{Binding Thumbnail.AnimationPosition.Position}"
                             Visibility="{Binding Thumbnail.AnimationPosition.Visibility}"/&gt;
  
                &lt;TextBlock DockPanel.Dock="Bottom" Height="40" 
                           TextWrapping="Wrap" TextTrimming="CharacterEllipsis" 
                           TextAlignment="Center" Text="{Binding Name}"/&gt;
  
              &lt;/DockPanel&gt;
            &lt;/DataTemplate&gt;
          &lt;/Setter.Value&gt;
        &lt;/Setter&gt;
      &lt;/Style&gt;
  
    &lt;/TabControl.Resources&gt;
  
    &lt;TabItem Header=""&gt;
  
      &lt;custom:MediaContainerListView x:Name="MediaContainerView"&gt;&lt;/custom:MediaContainerListView&gt;
  
    &lt;/TabItem&gt;
  
  &lt;/TabControl&gt;
  </code></pre>
  
  <p>Basically, I have two methods that start/stop the animation for each individual item.</p>
  
  <pre class="lang-cs prettyprint-override"><code>      public async void StartAnimation()
        {
           if( Count &gt; 1 )
           {
              Task thumbnailAnimationTask = AnimationTask( AnimationCancellationToken.Token );
              await thumbnailAnimationTask;
           }
        }
  
        public void StopAnimation()
        {
           AnimationCancellationToken.Cancel();
        }
  </code></pre>
  
  <p>I have two issues here.</p>
  
  <ol>
  <li>The ListView seems to realize all the items rather than only those visible or within the realization range. I suspect my XAML somehow kills the Virtualization and have tried many solutions with no success. Mind you I need my ListView to be scalable to the MainWindow's dimensions and not be of fixed hight and width.</li>
  <li>I need to call StartAnimation when an item is about to be realized and StopAnimation when it has left the view.</li>
  </ol>
  
  <p>Even though my ListView is not correctly Virtualized, if my understanding of how ObservableCollections work is correct, it's only the UI representation of the items that are managed by the Virtualization and not the items themselves i.e. calling the StartAnimation/StopAnimation from the Constructor/Destructor of the items don't help much as they are called for every single item at the time of creation anyway. </p>
  
  <p>Is there a neat way to somehow inform each item that they are about to be realized or leave the ListView view?</p>
  
  <p><strong>Update:</strong>
  The issue of virtualizing not working correctly was related to the <em>WrapPanel</em> and once I switched to <em>VirtualizingStackPanel</em> it started to work correctly. Unfortunately it's not exactly the same as a <em>WrapPanel</em> and since .NET framework does not offer a <em>VirtualizingWrapPanel</em>, I chose to use the one from <a href="https://virtualwrappanel.codeplex.com/" rel="nofollow">here</a>. It's not perfect but it does the job.</p>