title: How to update progress bar while working in the UI thread
body: <p>I have a <code>ProgressBar</code> and a <code>TreeView</code>.</p>
  
  <p>I populated the <code>TreeView</code> with a bunch of data, once it is applied I run through the <code>visual tree</code> of the <code>TreeView</code> basically forcing it to generate each of the <code>TreeViewItems</code>. I would like the <code>ProgressBar</code> to show how this is progressing.</p>
  
  <p>This is the behavior code that I run to create the <code>TreeViewItems</code>. It starts processing the items once <code>ItemsLoaded</code> property is set to true. It in turn updates a property in a singleton class to update the progress.</p>
  
  <pre><code>public class TreeViewBehaviors
  {
      public static readonly DependencyProperty ItemsLoadedProperty =
          DependencyProperty.RegisterAttached("ItemsLoaded", typeof(bool), typeof(TreeViewBehaviors),
          new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnItemsLoadedPropertyChanged)));
  
      public static bool GetItemsLoaded(DependencyObject obj)
      {
          return (bool)obj.GetValue(ItemsLoadedProperty);
      }
  
      public static void SetItemsLoaded(DependencyObject obj, bool value)
      {
          obj.SetValue(ItemsLoadedProperty, value);
      }
  
      private static void OnItemsLoadedPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
      {
          if ((bool)e.NewValue)
          {
              GetTotalNTreeViewItems((TreeView)sender, sender);
          }
      }
  
      public static readonly DependencyProperty NodesProcessedProperty =
          DependencyProperty.RegisterAttached("NodesProcessed", typeof(int), typeof(TreeViewBehaviors),
          new FrameworkPropertyMetadata(default(int), new PropertyChangedCallback(OnNodesProcessedPropertyChanged)));
  
      public static int GetNodesProcessed(DependencyObject obj)
      {
          return (int)obj.GetValue(NodesProcessedProperty);
      }
  
      public static void SetNodesProcessed(DependencyObject obj, int value)
      {
          if (GetNodesProcessed(obj) != value)
          {
              obj.SetValue(NodesProcessedProperty, value);
          }
      }
  
      private static void OnNodesProcessedPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
      {
          if (e.NewValue != null)
          {
              double trouble = Math.Round(((GetProgressMaximum(sender) / GetTotalNodesToProcess(sender)) * (int)e.NewValue), 1);
              TreeViewSingletonClass.Instance.DisplayProgress = trouble;
          }
      }
  
      public static readonly DependencyProperty TotalNodesToProcessProperty =
          DependencyProperty.RegisterAttached("TotalNodesToProcess", typeof(double), typeof(TreeViewBehaviors),
          new FrameworkPropertyMetadata(default(double)));
  
      public static double GetTotalNodesToProcess(DependencyObject obj)
      {
          return (double)obj.GetValue(TotalNodesToProcessProperty);
      }
  
      public static void SetTotalNodesToProcess(DependencyObject obj, double value)
      {
          obj.SetValue(TotalNodesToProcessProperty, value);
      }
  
  
      public static readonly DependencyProperty ProgressMaximumProperty =
          DependencyProperty.RegisterAttached("ProgressMaximum", typeof(double), typeof(TreeViewBehaviors),
          new FrameworkPropertyMetadata(default(double)));
  
      public static double GetProgressMaximum(DependencyObject obj)
      {
          return (double)obj.GetValue(ProgressMaximumProperty);
      }
  
      public static void SetProgressMaximum(DependencyObject obj, double value)
      {
          obj.SetValue(ProgressMaximumProperty, value);
      }
  
      private static void GetTotalNTreeViewItems(ItemsControl container, DependencyObject sender)
      {
          if (container != null)
          {
              container.ApplyTemplate();
              ItemsPresenter itemsPresenter = (ItemsPresenter)container.Template.FindName("ItemsHost", container);
              if (itemsPresenter != null)
              {
                  itemsPresenter.ApplyTemplate();
              }
              else
              {
                  // The Tree template has not named the ItemsPresenter, 
                  // so walk the descendents and find the child.
                  itemsPresenter = FindVisualChild&lt;ItemsPresenter&gt;(container);
                  if (itemsPresenter == null)
                  {
                      container.UpdateLayout();
                      itemsPresenter = FindVisualChild&lt;ItemsPresenter&gt;(container);
                  }
              }
  
              Panel itemsHostPanel = (Panel)VisualTreeHelper.GetChild(itemsPresenter, 0);
  
              // Ensure that the generator for this panel has been created.
              UIElementCollection children = itemsHostPanel.Children;
              for (int i = 0, count = container.Items.Count; i &lt; count; i++)
              {
                  TreeViewItem subContainer = (TreeViewItem)container.ItemContainerGenerator.ContainerFromIndex(i);
                  GetTotalNTreeViewItems(subContainer, sender);
                  SetNodesProcessed(sender, GetNodesProcessed(sender) + 1);
              }
          }
      }
  
      private static T FindVisualChild&lt;T&gt;(Visual visual) where T : Visual
      {
          for (int i = 0; i &lt; VisualTreeHelper.GetChildrenCount(visual); i++)
          {
              Visual child = (Visual)VisualTreeHelper.GetChild(visual, i);
              if (child != null)
              {
                  T correctlyTyped = child as T;
                  if (correctlyTyped != null)
                      return correctlyTyped;
  
                  T descendent = FindVisualChild&lt;T&gt;(child);
                  if (descendent != null)
                      return descendent;
              }
          }
          return null;
      }
  }
  </code></pre>
  
  <p><strong>Singleton Class</strong></p>
  
  <pre><code>public class TreeViewSingletonClass : INotifyPropertyChanged
  {
      private static double m_DisplayProgress = 0;
      public double DisplayProgress
      {
          get { return m_DisplayProgress; }
          set
          {
              if (m_DisplayProgress == value)
                  return;
              m_DisplayProgress = value;
              NotifyPropertyChanged();
          }
      }
  
      private static TreeViewSingletonClass m_Instance;
      public static TreeViewSingletonClass Instance
      {
          get
          {
              if (m_Instance == null)
                  m_Instance = new TreeViewSingletonClass();
              return m_Instance;
          }
      }
  
      private TreeViewSingletonClass(){}
  
      public event PropertyChangedEventHandler PropertyChanged;
  
      private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
      {
          if (PropertyChanged != null)
              PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
      }
  }
  </code></pre>
  
  <p><strong>XAML:</strong></p>
  
  <pre><code>&lt;ProgressBar Grid.Column="2" Grid.Row="1" Margin="5" 
               Width="20" Height="150" 
               VerticalAlignment="Top" 
               Value="{Binding Source={x:Static helpers:TreeViewSingletonClass.Instance}, Path=DisplayProgress}" 
               Maximum="{Binding ProgressMaximum}"  /&gt;
  </code></pre>
  
  <p>My issue is, every thing is being processed correctly, just the <code>ProgressBar</code> is not updating until the very end. I realise that the two are both working inline on the same <code>UI thread</code> so that will be the problem.</p>
  
  <p>So my question, with both of these working on the same thread how can I get this <code>ProgressBar</code> to update.</p>
  
  <p><strong>[EDIT]</strong></p>
  
  <p>This WPF is a <code>UserControl</code> in a <code>WinForm</code> <code>ElementHost</code>, I just placed the following into the WinForm so I can access <code>Application.Current</code></p>
  
  <pre><code>if ( null == System.Windows.Application.Current )
  {
     new System.Windows.Application();
  }
  </code></pre>
  
  <p>After trying to implement the second suggestion of Xavier's: Split up the work into smaller pieces and queue those pieces up individually with the dispatcher using BeginInvoke (for example, convert the body of a loop into a dispatcher call)</p>
  
  <p>So inside the <code>for</code> loop I stuck the following:</p>
  
  <pre><code>for (int i = 0, count = container.Items.Count; i &lt; count; i++)
  {
      Application.Current.Dispatcher.BeginInvoke(new Action(delegate()
      {
          TreeViewItem subContainer = (TreeViewItem)container.ItemContainerGenerator.ContainerFromIndex(i);
          GetTotalNTreeViewItems(subContainer, sender);
          SetNodesProcessed(sender, GetNodesProcessed(sender) + 1); 
      }));
  }
  </code></pre>
  
  <p>Unfortunately this has not worked, must be doing something wrong.</p>