title: Extra PropertyChanged needed after INotifyTaskCompletion completes its task
body: <p>I use the method of <a href="http://blog.stephencleary.com/2013/01/async-oop-3-properties.html" rel="nofollow">this blog</a> (last paragraph) with <code>INotifyTaskCompletion</code> to have async properties in a view-model. It works nicely but I had to adapt it somewhat and there lies my question - whether I did it correctly or not.</p>
  
  <p>View-model:</p>
  
  <pre><code>async Task&lt;ObservableCollection&lt;string&gt;&gt; GetInstancesAsync()
  {
      var instances = await TaskEx.Run(new Func&lt;List&lt;string&gt;&gt;(() =&gt; Agent.GetInstances()));
      return new ObservableCollection&lt;string&gt;(instances);
  }
  public INotifyTaskCompletion&lt;ObservableCollection&lt;string&gt;&gt; InstancesAsync { get; private set; }
  string instance;
  public string Instance
  {
      get { return instance; }
      set
      {
          instance = value;
          ProjectsAsync = NotifyTaskCompletion.Create(GetProjetsAsync(value));
          raisePropertyChanged("ProjectsAsync");
      }
  }
  </code></pre>
  
  <p>In the constructor I start off:</p>
  
  <pre><code>InstancesAsync = NotifyTaskCompletion.Create(GetInstancesAsync(value));
  raisePropertyChanged("InstancesAsync");
  </code></pre>
  
  <p>The databinding is simply <code>ItemsSource="{Binding InstancesAsync.Result}"</code>.
  The implementation of <code>INotifyTaskCompletion&lt;TResult&gt;</code> is not complicated, abbreviated: <code>task.ContinueWith(t =&gt; { PropertyChanged(this, new PropertyChangedEventArgs("Result")); };</code>  </p>
  
  <p>My understanding is as follows: after starting the task, <code>raisePropertyChanged("InstancesAsync")</code> has the effect that wpf tries to find <code>InstancesAsync.Result</code>. It finds <code>InstancesAsync</code> because this object is instantiated <em>before</em> the task starts, but Result is <em>null</em>. After completion of the task, wpf receives <code>PropertyChanged("Result")</code> and via the <em>existing</em> accessor <code>InstancesAsync</code> <code>Result</code> is now found.<br>
  The ItemsSource in wpf is populated and now wpf must trigger the Binding for SelectedItem and in this way go to property <code>Instance</code>. Because in my case, there another async property task is started.
  For that to happen I need to kick off <code>raisePropertyChanged("Instance")</code> after the task completes.</p>
  
  <p>I solved it by passing my <code>raisePropertyChanged</code> as a delegate and the property name as a string to the implementation class of <code>INotifyTaskCompletion</code>.</p>
  
  <p>I am content with this solution, but perhaps I am overlooking something?<br>
  <strong>EDIT:</strong><br>
  it turned out that the straightforward way of Mr. Cleary is correct, however only when <code>IsSynchronizedWithCurrentItem=True</code>. Otherwise there is no automatic selection of the first item of the list.</p>
  
  <p>Another, related, issue popped up.<br>
  I added to <code>INotifyTaskCompletion</code> the check <code>if (propertyChanged == null) throw new Exception("PropertyChanged: no subscribers");</code> because I have had issues with that before.  </p>
  
  <p>Then in the setter of <code>Instance</code> I added:</p>
  
  <pre><code>private string _instance;
  public string Instance
  {
    get { return _instance; }
    set
    {
      if (ProjectsAsync == null &amp;&amp; !Properties.Settings.Default.Instance.IsNullOrEmpty())
      {
          value = InstantiesAsync.Result.FirstOrDefault(i =&gt; i == Properties.Settings.Default.Instance);
      }
      _instance = value;
      raisePropertyChanged("Instance");
      ProjectsAsync = NotifyTaskCompletion.Create(GetProjetsAsync(value));
    }
  }
  </code></pre>
  
  <p>The idea here is to override the default selection of item 0 of the underlying <code>ICollectionView</code>.<br>
  Then the Exception I mentioned occurs. I have to manipulate the <code>CurrentItem</code> of the <code>ICollectionView</code> instead of arbitrarily changing the value. Any ideas?</p>
  
  <p>My current solution is to avoid <code>IsSynchronizedWithCurrentItem=True</code> altogether and set the SelectedItem of the list when the list is set to a new value.<br>
  Therefore I have to subscribe to the async PropertyChanged event:</p>
  
  <pre><code>instancesAsync.PropertyChanged += instancesAsync_Ready;
  </code></pre>
  
  <p>And there:</p>
  
  <pre><code>if (e.PropertyName == "Result")
      {
         if (instance == null &amp;&amp; !Properties.Settings.Default.Instance.IsNullOrEmpty())
         {
             Instance = InstancesAsync.Result.FirstOrDefault(i =&gt; i == Properties.Settings.Default.Instance);
         }
     }
  </code></pre>