title: How to properly implement Busy Indicator from WPF Extended Toolkit
body: <p>Ok, I have been struggling with this issue for quite some time and have read article after article trying to get an idea on the issue. I am trying to implement the Busy Indicator and am only partially successful. I have a Shell view that I have wrapped with the BusyIndicator like so:</p>
  
  <pre><code>&lt;Window x:Class="Foundation.Shell"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:controls="clr-namespace:Library.Controls.Views;assembly=Library"
      xmlns:l="clr-namespace:Library.StaticClasses"
      xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
      Name="ShellView"
      Style="{StaticResource BusyWindowStyle}"
      SourceInitialized="Window_SourceInitialized"
      DataContext="{StaticResource ShellVM}"&gt;
  
      &lt;xctk:BusyIndicator x:Name="ShellBusyIndicator" IsBusy="{Binding IsBusy}"  DisplayAfter="0"&gt;
          &lt;Grid&gt;
              &lt;!--Content Here --&gt;
          &lt;/Grid&gt;
      &lt;/xctk:BusyIndicator&gt;
  </code></pre>
  
  <p>Following the MVVM pattern, I have a ShellViewModel that looks like so:</p>
  
  <pre><code>public class ShellViewModel : ViewModelBase
  {
      #region constructor(s)
  
      public ShellViewModel()
      {
          StateManager.IsBusyChange += new StateManager.IsBusyHandler(IsBusyEventAction);
      }
  
      #endregion constructor(s)
  
      #region properties
  
      private bool _IsBusy;
      public bool IsBusy
      {
          get
          {
              return _IsBusy;
          }
          set
          {
              if (_IsBusy != value)
              {
                  _IsBusy = value;
                  OnPropertyChanged("IsBusy");
              }
          }
      }
  
      private string _IsBusyMessage;
      public string IsBusyMessage
      {
          get
          {
              return _IsBusyMessage;
          }
          set
          {
              if (_IsBusyMessage != value)
              {
                  _IsBusyMessage = value;
                  OnPropertyChanged("IsBusyMessage");
              }
          }
      }
  
      #endregion properties
  
      #region actions, functions, and methods
  
      private void IsBusyEventAction(object sender, EventArgs e)
      {
          if (StateManager.IsBusy)
          {
              this.IsBusy = true;
              this.IsBusyMessage = StateManager.IsBusyMessage;
          }
          else
          {
              this.IsBusy = false;
          }
      }
  
      #endregion actions, functions, and methods
  }
  </code></pre>
  
  <p>Next, I am using a static class called StateManager that I can call from anywhere that will trigger the busy indicator:</p>
  
  <pre><code>public static class StateManager
  {
      public static String IsBusyMessage { get; set; }
  
      public static void IsBusyProcess(Action action)
      {
          IsBusyProcess(action, "Processing...");
      }
  
      public static void IsBusyProcess(Action action, String isBusyMessage)
      {
          IsBusyMessage = isBusyMessage;
          IsBusy = true;
          Application.Current.Dispatcher.Invoke(action, System.Windows.Threading.DispatcherPriority.Background);
          IsBusy = false;
      }
  
      private static bool _IsBusy;
      public static bool IsBusy
      {
          get
          {
              return _IsBusy;
          }
          set
          {
              if (_IsBusy != value)
              {
                  _IsBusy = value;
  
                  IsBusyChange(null, null);
              }
          }
      }
  
      public delegate void IsBusyHandler(object sender, EventArgs e);
  
      public static event IsBusyHandler IsBusyChange;
  }
  </code></pre>
  
  <p>Finally, I am triggering the busy indicator in code like so:</p>
  
  <pre><code>StateManager.IsBusyProcess(() =&gt;
          {
              this.Validate();
  
              if (!HasValidationErrors)
              {
                  if (this.CustomerControlVM.SaveCustomer() != 0)
                  {
                      VehicleControlVM.VehicleModel.CustomerID = this.CustomerControlVM.CustomerModel.CustomerID;
                      this.VehicleControlVM.SaveVehicle();
  
                      ComplaintsView complaintsControl = new ComplaintsView();
  
                      (complaintsControl.DataContext as ComplaintsViewModel).CurrentVehicle = this.VehicleControlVM.VehicleModel;
                      (complaintsControl.DataContext as ComplaintsViewModel).CurrentCustomer = this.CustomerControlVM.CustomerModel;
                      StateManager.LoadView(complaintsControl, PageTransitionType.SlideLeft);
                  }
              }
  
              StateManager.IsBusy = false;
          });
  </code></pre>
  
  <p>To summarize, the StateManager can be called from anywhere in the application. When the StateManager.IsBusy property is changed, an event, which is subscribed to in the ShellViewModel, is fired. When this happens, the IsBusy property in the ShellViewModel is set to true supposedly causing the IsBusy indicator to show. The logic is working fine in the sense that the IsBusy in the ShellViewModel is being set and the busy indicator evens shows as expected. What isn't working right is that the busy indicator does not animate. It simply stays stagnate. I feel like this is a threading issue but either my understanding of the UI thread is tilted or I am not seeing something that is hopefully obvious to you. I realize the IsBusy logic cannot be on the same thread as the UI, but I would think that since my logic is happening in the view model, it shouldn't be an issue. Am I wrong? Any ideas or thoughts? One other thing that might be helpful: I was having trouble even getting the indicator to show and created this post which was resolved: <a href="https://stackoverflow.com/questions/25194615/how-to-implement-busy-indicator-in-application-shell/25195293#25195293">How to implement busy indicator in application shell</a></p>