title: How to stop DataGrid from flickering when using ObservableCollection?
body: <p>I've been battling with <code>WPF</code> and the <code>ObservableCollection</code> for quite some time and now I need some help.</p>
  
  <p><strong>This is the setup and requirements</strong></p>
  
  <ul>
  <li>Using MongoDB as the backing database</li>
  <li>Storing huge amounts of log data in the database</li>
  <li>The UI must be able to display the logs as they are inserted into the database (real time-ish)</li>
  <li>The UI DataGrid is bound to an <code>ObservableCollection</code></li>
  <li>The UI DataGrid is and must be paged due to memory usage and having millions of records</li>
  <li>When viewing the log, if a new entry is created and displayed, one must be removed as well; this is just because of paging and having a set page size (50 log entries will only ever be shown at one time)</li>
  <li>Using ActiveMQ to signal when a new log entry has been created</li>
  </ul>
  
  <p>So essentially this is a rolling log view where one entry comes in and one entry goes out. I must maintain the selected item and show updates in real time (which is why I'm using the <code>ObservableCollection</code>). The log can be filtered and pages can be navigated so I figured it would be easiest to fetch the entire page when there are new log entries and display it; this would also allow me to get entries that might have been missed previously.</p>
  
  <p>I've had so many issues with this, including problems with updating the collection on a background thread and the most recent is <code>DataGrid</code> "flickering" when a new entry is created. I'm assuming the flickering is caused by refreshing the whole collection every time but the alternative (adding and removing items manually) is much more complex and I'd prefer not to go that route due to the complexities of the filtering and paging.</p>
  
  <p>Are there any good patterns or suggestions for stopping this "flickering" or maybe a better way to implement a filterable log view that updates in real time?</p>
  
  <p><strong>Xaml</strong></p>
  
  <pre><code>&lt;DataGrid ItemsSource="{Binding Entries, IsAsync=True}"
        AutoGenerateColumns="False" IsReadOnly="True"
        CanUserSortColumns="False"
        EnableColumnVirtualization="True" EnableRowVirtualization="True"
        VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling"&gt;
      &lt;DataGrid.Columns&gt;
          &lt;DataGridTextColumn Header="Timestamp" Binding="{Binding Timestamp}" /&gt;
          &lt;DataGridTextColumn Header="From" Binding="{Binding MessageFrom}" /&gt;
          &lt;DataGridTextColumn Header="To" Binding="{Binding MessageTo}" /&gt;
          &lt;DataGridTextColumn Header="Type" Binding="{Binding MessageType}" /&gt;
      &lt;/DataGrid.Columns&gt;
  &lt;/DataGrid&gt;
  </code></pre>
  
  <p>ViewModel code for binding that I've used</p>
  
  <pre><code>//option 1
  public ViewModel() { this.Entries = new ObservableCollection&lt;Model&gt;(); }
  
  public void UpdateData()
  {
      this.Entries.Clear();
      foreach (Model m in FetchModels())
          this.Entries.Add(m);
  }
  
  public ObversableCollection&lt;Model&gt; Entries { get; private set; }
  
  //option 2
  private List&lt;Model&gt; m_Entries = new List&lt;Model&gt;();
  
  public void UpdateData()
  {
      this.m_Entries.Clear();
      this.m_Entries.AddRange(FetchModels());
      this.NotifyPropertyChanged(() =&gt; this.Entries);
  }
  
  public ObversableCollection&lt;Model&gt; Entries { get { return new ObservableCollection&lt;Model&gt;(this.m_Entries); } }
  
  //option 3
  public ViewModel() { this.Entries = new ObservableCollection&lt;Model&gt;(); }
  
  public void UpdateData()
  {
      var tmp = this.Entries;
      this.Entries = null;
  
      tmp.Clear();
      foreach (Model m in FetchModels())
          tmp.Add(m);
  
      this.Entries = tmp;
      this.NotifyPropertyChanged(() =&gt; this.Entries);
  }
  
  public ObversableCollection&lt;Model&gt; Entries { get; private set; }
  </code></pre>
  
  <p>As soon as I remember more things I've tried, I'll post it.</p>