title: Update ObservableCollection from BackgroundWorker/ProgressChanged Event
body: <p>I'm writing a simple tool for troubleshooting computers. Basically its just a WPF Window with a <code>ListBox</code> bound to an <code>ObservableCollection&lt;ComputerEntry&gt;</code> where <code>ComputerEntry</code> is a simple class containing the computer host name, and Status. All the tool does is ping each compute name in the list, and if a response is received <code>ComputerEntry.Status</code> is updated to indicate the computer is connected to the network somewhere...</p>
  
  <p>Pinging however can take some time, up to a couple seconds per computer depending on if it has to timeout or not. So I'm running the actual ping in a <code>BackgroundWorker</code> and using the <code>ReportProgress</code> method to update the UI.</p>
  
  <p>Unfortunately the <code>ObservableCollection</code> does not seem raise the <code>PropertyChanged</code> event after the objects are updated. The collection does update with the new information, but the status never changes in the <code>ListBox</code>. Presumably because it does not know that the collection has changed.</p>
  
  <p>[EDIT]
  <strong>Per fantasticfix, the key here is: "The ObservableCollection fires just when the list gets changed (added, exchanged, removed)." Since I was setting the properties of the object instead of modifying it, the ObservableCollection was not notifying the list of the change -- it didn't know how. After implenting <code>INotifyPropertyChanged</code> everything works fine. Conversly, replacing the object in the list with a new updated instance will also fix the problem.</strong>
  [/EDIT]</p>
  
  <p>Btw I'm using C# 3.5 and I'm not in a position where I can add additional dependancies like TPL.</p>
  
  <p>So as a simplified example [that won't compile without more work...]:</p>
  
  <pre><code>//Real one does more but hey its an example...
  public class ComputerEntry
  {
      public string ComputerName { get; private set; }
      public string Status { get; set; }
  
      public ComputerEntr(string ComputerName)
      {
          this.ComptuerName = ComputerName;
      }
  }
  
  
  //...*In Window Code*...
  private ObservableCollection&lt;ComputerEntry&gt; ComputerList { get; set; }
  private BackgroundWorker RefreshWorker;
  
  private void Init()
  {
       RefreshWorker = new BackgroundWorker();
       RefreshWorker.WorkerReportsProgress = true;
       RefreshWorker.DoWork += new DoWorkEventHandler(RefreshWorker_DoWork);
       RefreshWorker.ProgressChanged += new ProgressChangedEventHandler(RefreshWorker_ProgressChanged);
  }
  
  private void Refresh()
  {
      RefreshWorker.RunWorkerAsync(this.ComputerList);
  }
  
  private void RefreshWorker_DoWork(object sender, DoWorkEventArgs e)
  {
      List&lt;ComputerEntry&gt; compList = e as List&lt;ComputerEntry&gt;;
      foreach(ComputerEntry o in compList)
      {
          ComputerEntry updatedValue = new ComputerEntry();
          updatedValue.Status = IndicatorHelpers.PingTarget(o.ComputerName);
          (sender as BackgroundWorker).ReportProgress(0, value);
      }
  }
  
  private void RefreshWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
  {
      ComputerEntry updatedValue = new ComputerEntry();
      if(e.UserState != null)
      {
          updatedValue = (ComputerEntry)e.UserState;
          foreach(ComputerEntry o in this.ComputerList)
          {
              if (o.ComputerName == updatedValue.ComputerName)
              {
                  o.Status = updatedValue.Status;
              }
          }
      }
  }
  </code></pre>
  
  <p>Sorry for the jumble but its rather long with all the support code. Anyways, <code>void Refresh()</code> is called from a DispatcherTimer (which isn't shown), that starts <code>RefreshWorker.RunWorkerAsync(this.ComputerList);</code>.</p>
  
  <p>I've been fighting this for a few days so I'm now to the point where I'm not actually attempting to modify the objects referenced in the <code>ObservableCollection</code> directly anymore. Hence the ugly looping through the ComputerList collection and setting the properties directly.</p>
  
  <p>Any idea whats going on here and how I can fix it?</p>