WPF Spinner – take two

The WPF wait indicator which I have published a while ago proved to be good as a starting point but somewhat limited when it came to using it in production: the major problem was the fact that changing its appearance required pretty much  total rework. As soon as I put it to use, new requirements arrived and it  was clear that we need a slightly different approach. First of all there was the issue of size, as sometimes you may need a smaller wait indicator, secondly the content was not very flexible and if it was to be changed, the key frame animation driving the whole thing needed to be reworked from scratch. So after a bit of head scratching I opted for a “lookless” approach and decided to implement a custom WPF ContentControl which would provide scaling and animation capabilities. To cut the long story short you can see the final effects below:


The control is dead easy to use as the following piece of XAML illustrates.

   1:         <Spinner:ContentSpinner Margin="10"
   2:                                  BorderBrush="Black"
   3:                                  BorderThickness="2" />


To make our life easier, the ContentSpinner provides a couple of dependency properties: first there is the Scale property which allows the user to scale the content, secondly NumberOfFrames property controls how many frames will be included in the animation and thirdly RevolutionsPerSecond drives a number of rotations the content will make each second. Also if you are not happy with the default content feel free to provide your own as in the XAML below:

   1:          <Spinner:ContentSpinner Margin="10"
   2:                                  BorderBrush="Black"
   3:                                  BorderThickness="2"
   4:                                  NumberOfFrames="8"
   5:                                  Content="{StaticResource blueDotsCanvas}">
   7:          </Spinner:ContentSpinner>


The following code fragment illustrates the most important aspects of the control. The basic idea is that the control applies RotateTransform to its content and the transform is then animated using DoubleAnimationUsingKeyFrames. The number of frames is driven by the NumberOfFrames property and duration of the animation is calculated based on the number of required RevolutionsPerSecond.

   1:  private void StartAnimation()
   2:  {
   3:      if (_content == null)
   4:          return;
   6:      var animation = GetAnimation();
   8:      _content.LayoutTransform = GetContentLayoutTransform();
   9:      _content.RenderTransform = GetContentRenderTransform();
  11:      _storyboard = new Storyboard();
  12:      _storyboard.Children.Add(animation);
  14:      _storyboard.Begin(this);
  15:  }
  17:  private void StopAnimation()
  18:  {
  19:      if (_storyboard != null)
  20:      {
  21:          _storyboard.Remove(this);
  22:          _storyboard = null;
  23:      }
  24:  }
  26:  private void RestartAnimation()
  27:  {
  28:      StopAnimation();
  29:      StartAnimation();
  30:  }
  32:  private Transform GetContentLayoutTransform()
  33:  {
  34:      return new ScaleTransform(ContentScale, ContentScale);
  35:  }
  37:  private Transform GetContentRenderTransform()
  38:  {
  39:      var rotateTransform = new RotateTransform(0, _content.ActualWidth / 2 * ContentScale, _content.ActualHeight / 2 * ContentScale);
  40:      RegisterName(ANIMATION, rotateTransform);
  42:      return rotateTransform;
  43:  }
  45:  private DoubleAnimationUsingKeyFrames GetAnimation()
  46:  {
  47:      NameScope.SetNameScope(this, new NameScope());
  49:      var animation = new DoubleAnimationUsingKeyFrames();
  51:      for (int i = 0; i < NumberOfFrames; i++)
  52:      {
  53:          var angle = i * 360.0 / NumberOfFrames;
  54:          var time = KeyTime.FromPercent(((double)i) / NumberOfFrames);
  55:          DoubleKeyFrame frame = new DiscreteDoubleKeyFrame(angle, time);
  56:          animation.KeyFrames.Add(frame);
  57:      }
  59:      animation.Duration = TimeSpan.FromSeconds(1 / RevolutionsPerSecond);
  60:      animation.RepeatBehavior = RepeatBehavior.Forever;
  62:      Storyboard.SetTargetName(animation, ANIMATION);
  63:      Storyboard.SetTargetProperty(animation, new PropertyPath(RotateTransform.AngleProperty));
  65:      return animation;
  66:  }

There are a couple of things which I need to mention though when it comes to the custom content: if you want it to be a part of resource dictionary, you may need to set the x:Shared property to False as otherwise it will be impossible to display two spinners simultaneously. Secondly the content should be symmetrical and its horizontal and vertical alignment needs to be set to Center as otherwise the spinner may get a bit wonky. Sample code and the control are available as part of the SharpFellows.Toolkit.

September 20 2010

The Mythical “Private Office”

Several years ago I read an interesting book dealing with, among other things, developers productivity: based on research done at  IBM’s Santa Teresa facility, the author suggested that the productivity of developers can be substantially higher than industry average provided that they have private offices. Apparently, if you allow developers to work in an environment which does not provide any distractions, they are able to crank more code. Fair enough. I have to admit here that I read the text several years ago, so I might have gotten some names wrong here, but the idea stuck with me (and some other people as well) for a long time: the private office was the holy grail of software development.

I see and hear similar ideas surfacing from time to time and what amazes me nowadays is the fact that people still believe that number of lines of code (commonly used measure of developers productivity) is indeed a valid metric. If so, how come we’re all not paid by the number of lines we produce each month?

People pay us to develop software, hoping that they will get more out of it when it is up and running. When evaluating software projects they are interested in the value the product can provide to their business, not in the lines of code cranked in order to produce it. And this leads to an interesting conclusion: the amount of code anyone writes per month is completely irrelevant, it’s the value they provide that matters.

In contrast to “private office” camp, one of the fundamental aspects of Agile development is co-location of team members: the team should occupy the same office space. I have to admit that initially I was a bit skeptical, wondering why are the prophets of Agile so insistent on entire teams (not only devs) working so close together. But if you were lucky enough to work on a properly run agile project, you must have witnessed first hand the continuous buzz of conversation between team members: people will bounce ideas of each other, testers will harass developers and vice versa, pairs will discuss or argue approaches to solving problems etc. Some will say that this is not the most productive environment, and surely it’s not, but only if  measure productivity by the amount of code cranked per man-month.

The “conversation-bus” allows team members to publish/subscribe on demand so they can “plug” themselves into any conversation at any time in order to either add something of value or get something out of it. This has two major effects: first of all it promotes knowledge sharing and secondly (and more importantly) it allows pretty much anyone to contribute and add “value”. If you ask me, this is far more important than time lost writing code as out of those tiny conversation a better solution will invariably emerge. So keep the conversation-bus up and running and for those rare moments when you want to be all on your own get yourself a pair of headphones.

On the other hand if you ever hear someone on your team saying  “oh no, this is not the way you do it, why didn’t you ask?”, or people generally complaining about “communication”, read between the lines: they are not complaining about communication, they are complaining that they were not involved in the decision making process and no amount of meetings, emails, approvals, committees, steering groups or similar “remedies” is going to change it. Deprive people of ability to contribute, lock them in cells (or private offices) and the net effect is sinking team morale as there is nothing more frustrating than seeing your teammates trying to reinvent the wheel and invariably ending up with a square. Trust me, I have seen it way too many times, very often through the window of my virtual “private office”.

September 9 2010

Asynchronous WPF Commands

Programming applications for Windows has always been and event-driven affair: we’d place a control on a form, attach an event handler to it and whack some code behind to handle it. Job done. Unfortunately this approach is not very testable and as you’ve probably gathered by now, we’re very much interested in testability around here. There are couple of possible solutions to this problem and one of them (which works particularly well in WPF) is to replace event handlers with commands. This allows the view to be loosely coupled to the underlying “view model” and Darius Collins blogged about this approach using delegate WPF commands. There is also an excellent article by Josh Smith available on MSDN which discusses this pattern (Model-View-ViewModel) in detail.

To cut the long story short, the version of self-updateable DelegateCommand<T> (or RelayCommand<T> as Josh Smith calls it) is now part of the Sharpfellows.Toolkit but as it is being discussed extensively in the posts I have already mentioned I will not repeat myself here. Having said that, I feel I need to mention a minor deficiency of the UpdateableCommand<T> (as we call it): there are sadly some rare cases when the command does not work as expected when it comes to enabling/disabling the associated UI element. This is simply due to the RequerySuggested event is being raised in rather mysterious circumstances when the command manager “thinks” something may require refresh. This may not always work well with your app, so you may need to call CommandManager.InvalidaterequerySuggested() method to force it. Luckily the behaviour is repeatable and easy to spot so you do not have to worry about the app working erratically.

Asynchronous command

As it often happens, in order to keep the UI responsive, some of the commands need to execute the handler on a background thread. This is usually done using BackgroundWorker which provides convenient completion callback executing on the UI thread. There are however two major problems with this approach: first of all the threading code creates unnecessary and repeatable noise, cluttering the view model with “how” rather than letting it focus on the “what”, and secondly the multithreading introduces serious complexity into unit tests of the view model. To solve both of those issues I came up with UpdateableAsyncCommand<T> which, as the name implies, is capable of executing the command asynchronously. The clever bit about it is the fact that instead of directly using the threading API to execute the handler, the async command delegates the task of executing it to an object implementing IThreadingService interface (see below).

   1:  /// <summary>
   2:  /// Provides facilities for background tasks
   3:  /// </summary>
   4:  public interface IThreadingService
   5:  {
   6:      /// <summary>
   7:      /// Queues the execution of a task
   8:      /// </summary>
   9:      /// <param name="work"></param>
  10:      void QueueExecution(Action work);
  12:      /// <summary>
  13:      /// Queues the execution of a task and calls back when it is complete
  14:      /// </summary>
  15:      /// <param name="work"></param>
  16:      /// <param name="completionCallback"></param>
  17:      void QueueExecution(Action work, Action completionCallback);
  19:      /// <summary>
  20:      /// Queues the execution of a task with callback for successful completion and failure
  21:      /// </summary>
  22:      /// <param name="work"></param>
  23:      /// <param name="completionCallback"></param>
  24:      /// <param name="errorCallback"></param>
  25:      void QueueExecution(Action work, Action completionCallback, Action<Exception> errorCallback);
  26:  }

You may be wondering why on earth would we introduce an abstraction to be put on top of relatively simple threading API, but the reasons become clear when it comes to unit testing. UpdateableAsyncCommand<T> allows us to inject it with an implementation of the IThreadingService which executes the method synchronously. This fake implementation (provided for your convenience in the form of SynchronousThreadingService) allows the unit tests to run synchronously and shifts their focus to the business flow and interaction of components, rather than obscuring the picture with complex synchronisation code. The async command exposes IsBusy property which is set to true whenever the command handler is executing. As the UpdateableAsyncCommand<T> implements INotifyPropertyChanged you can even use the IsBusy property to drive the state of your UI. The following code fragment illustrates the most important aspects of the UpdateableAsyncCommand<T>

   1:  /// <summary>
   2:  /// Implements an asynchronous command
   3:  /// </summary>
   4:  /// <typeparam name="T"></typeparam>
   5:  public class UpdateableAsyncCommand<T> : NotifyPropertyChangedBase, IAsyncCommand
   6:  {
   7:      private readonly IThreadingService _threadingService;
   8:      private readonly Action<T> _executeMethod;
   9:      private readonly Func<T, bool> _canExecuteMethod;
  10:      private readonly Action _completionCallback;
  11:      private readonly Action<Exception> _errorCallback;
  12:      private bool _isBusy;
  14:      /// <summary>
  15:      /// Initializes a new instance of the <see cref="UpdateableAsyncCommand&lt;T&gt;"/> class.
  16:      /// </summary>
  17:      /// <param name="threadingService">The threading service </param>
  18:      /// <param name="executeMethod">The execute method.</param>
  19:      /// <param name="canExecuteMethod">The method which determines if the command can be executed.</param>
  20:      /// <param name="completionCallback">The method to be executed when the command handler completes</param>
  21:      /// <param name="errorCallback">The error callback.</param>
  22:      public UpdateableAsyncCommand(IThreadingService threadingService, Action<T> executeMethod, Func<T, bool> canExecuteMethod, Action completionCallback, Action<Exception> errorCallback)
  23:      {
  24:          // Sanity checks omitted...
  25:          _threadingService = threadingService;
  26:          _executeMethod = executeMethod;
  27:          _canExecuteMethod = canExecuteMethod;
  28:          _completionCallback = completionCallback;
  29:          _errorCallback = errorCallback;
  30:      }
  32:      /// <summary>
  33:      /// Defines the method that determines whether the command can execute in its current state.
  34:      /// </summary>
  35:      /// <param name="parameter">Data used by the command.  If the command does not require data to be passed, this object can be set to null.</param>
  36:      /// <returns>
  37:      /// true if this command can be executed; otherwise, false.
  38:      /// </returns>
  39:      public bool CanExecute(object parameter)
  40:      {
  41:          return !IsBusy && _canExecuteMethod((T) parameter);
  42:      }
  44:      /// <summary>
  45:      /// Occurs when changes occur that affect whether or not the command should execute.
  46:      /// </summary>
  47:      event EventHandler ICommand.CanExecuteChanged
  48:      {
  49:          add { CommandManager.RequerySuggested += value; }
  50:          remove { CommandManager.RequerySuggested -= value; }
  51:      }
  53:      /// <summary>
  54:      /// Executes the command with given parameter.
  55:      /// </summary>
  56:      /// <param name="parameter">The parameter.</param>
  57:      public void Execute(object parameter)
  58:      {
  59:          if ( IsBusy )
  60:              throw new InvalidOperationException("Concurrent execution of the command is not supported.");
  62:          IsBusy = true;
  64:          _threadingService.QueueExecution(() => _executeMethod((T) parameter), CommandFinished, CommandError );
  65:      }
  67:      /// <summary>
  68:      /// Gets or sets a value indicating whether this instance is busy.
  69:      /// </summary>
  70:      /// <value><c>true</c> if this instance is busy; otherwise, <c>false</c>.</value>
  71:      public bool IsBusy
  72:      {
  73:          get { return _isBusy; }
  74:          private set
  75:          {
  76:              if (_isBusy == value)
  77:                  return;
  79:              _isBusy = value;
  80:              // As the IsBusy may be set from the background thread, we ned to "poke" the 
  81:              // command manager to let it know it may be a good idea to check the command's CanExecute
  82:              CommandManager.InvalidateRequerySuggested();
  83:              OnPropertyChanged(() => IsBusy);
  84:          }
  85:      }
  87:      private void CommandFinished()
  88:      {
  89:          _completionCallback();
  90:          IsBusy = false;
  91:      }
  93:      private void CommandError(Exception ex)
  94:      {
  95:          _errorCallback(ex);
  96:          IsBusy = false;
  97:      }
  98:  }


More on the IThreadingService

The contract for the threading service is quite similar to that of IScheduler (found in reactive extensions) and for a while I was thinking if we should not use it instead. It became clear however that more often than not we need to call back to UI thread when the command handler is finished. This in turn forces use of SynchronisationContext, which is not available when running unit tests on the background thread (as some test runners do). As already mentioned we use SynchronousThreadingService in unit tests which alleviates the need to use SynchronizationContext altogether.

The concept of the IThreadingService has one more benefit: as the service is usually injected by an IoC container, it is very easy to switch from asynchronous to synchronous execution mode simply by replacing the implementation. This may be very helpful when debugging an application when we suspect the issue may be caused a misbehaving thread.

PS: To pay credit where it is due, I feel I need to mention that the threading service code included in the toolkit has been authored by John Rayner. The original idea however came from Dave Hanson who since then patented it and made enough money in royalties to leave his job and embark on a year long journey across Australia :)

Putting it all together

To illustrate the use of asynchronous commands I developed a simple (and rather silly) Web search application called Bingo. The app uses Microsoft’s Bing engine API and the search, as you would expect, is being executed using async command. For what it is, the sample may seem seriously over-engineered but I wanted to illustrate how the async command fits into the big picture of MVVM application.


As you can see from the screenshot above, in spite of all the years spent mastering Microsoft technologies, our website still does not deserve #1 spot in the Bing search results for “sharpfellows”… How disappointing ;) 

PS: The sample is obviously available as part of the toolkit.

September 1 2010

WPF “Drag and Drop” – doing it the MVVM way

I have been recently involved in a WPF/Prism project where one of the requirements was to allow the user to move rather large sums of money with the mouse. Think of moving the money from one account to another but with potential of serious loss if you drop it in between. When I trawled the net for examples of drag & drop in WPF, I noticed that the vast majority of them deal with the visual aspects of the operation, mixing business logic with the code behind which in turn results in code which is pretty much un-testable (in a unit testing sense). If  you take a closer look at any of the drag and drop code, it becomes obvious that the operation has a number of distinct aspects to it, some of which can be delegated to the “business logic component” offering potentially better testability:

  1. Drag and drop is initiated when the user presses the mouse and moves it by a certain distance. This requires event handling somewhere in the code behind. This code has to be potentially repeated over and over again for different controls.
  2. At the time the drag and drop is initiated, we hand over the mouse handling to the OS, but we still need to provide the data and we need to indicate what can be done with the object (Move, Copy etc). This would be best handled by the view model.
  3. While the mouse is being dragged we may need to provide some visual feedback as to what is going to happen when the object will get dropped. This again would be best handled by the view model but needs to be initiated from an event handler.
  4. Once the object is dropped, we just need to consume it but the operation requires Drop event handler in the code behind.

After a bit of head scratching and various discussions with John, I managed to come up wit ha solution which allows the drag and drop logic to be both reusable and testable. The main actors are as follows:

  1. DragSourceBehaviour  implements the event handling required to initiate the drag operation
  2. An object implementing IDragSource interface provides the data to be dragged
  3. DropTargetBehaviour implements drop related event handlers
  4. Object implementing IDropTarget handles the business logic of the “drop”
  5. Helper classes provide shortcuts for implementing both IDropTarget and IDragSource

The rest of this post discusses details of the implementation.

Handling the “Drag”

The start the drag & drop we need two event handlers: one to handle PreviewMouseButtonDown event and record the position and another one to handle PreviewMouseMove to see if the mouse have moved far enough to initiate drag & drop. Implementing those handlers over and over again in the code behind is not my idea of fun, so obviously another solution is required and a WPF behaviour fits the bill nicely. The drag and drop operation also needs a piece of data that will be dragged and we need to know what sort of drag operation will be supported: as indicated earlier this would be best handled by the view model.

To glue the event handling aspects and the data handling aspect together, I came up with the attached property of IDragSource type exposed by the DragSourceBehaviour. Once the property is set to a non null value, the behaviour will take care of the event handling while still delegating the task of providing data to implementation of IDragSource. I hope the following fragment from the DragSourceBehaviour class explains it all:

   1:  private static void PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
   2:  {
   3:      _startPoint = e.GetPosition(null);
   4:  }
   6:  private static void MouseLeave(object sender, MouseEventArgs e)
   7:  {
   8:      // Need to reset since the mouse left in order to prevent mouse movement 
   9:      // in another element to pick drag an drop
  10:      _startPoint = null;
  11:  }
  13:  private static void PreviewMouseMove(object sender, MouseEventArgs e)
  14:  {
  15:      if (e.LeftButton != MouseButtonState.Pressed || _startPoint == null)
  16:          return;
  18:      if(!HasMouseMovedFarEnough(e))
  19:          return;
  21:      var dependencyObject = (FrameworkElement) sender;
  22:      var dataContext = dependencyObject.GetValue(FrameworkElement.DataContextProperty);
  23:      var dragSource = GetDragSource(dependencyObject);
  25:      if (dragSource.GetDragEffects(dataContext) == DragDropEffects.None)
  26:          return;
  28:      DragDrop.DoDragDrop(dependencyObject,
  29:                          dragSource.GetData(dataContext),
  30:                          dragSource.GetDragEffects(dataContext));
  32:  }


The object implementing IDragSource interface does not have to be in any sense “related” to the visual initiating the operation, but whoever implements the IDragSource would be often interested in what is the data context of the object and for this reason IDragSource takes object “dataContext” parameter to both of it’s methods

   1:      /// <summary>
   2:      /// Business end of the drag source
   3:      /// </summary>
   4:      public interface IDragSource
   5:      {
   6:          /// <summary>
   7:          /// Gets the supported drop effects.
   8:          /// </summary>
   9:          /// <param name="dataContext">The data context.</param>
  10:          /// <returns></returns>
  11:          DragDropEffects GetDragEffects(object dataContext);
  13:          /// <summary>
  14:          /// Gets the data.
  15:          /// </summary>
  16:          /// <param name="dataContext">The data context.</param>
  17:          /// <returns></returns>
  18:          object GetData(object dataContext);
  19:      }

Implementing IDragSource interface over and over again may become tedious very quickly so I came up wit ha shortcut for implementing the interface which simply takes two delegates to be executes as and when required:

   1:  /// <summary>
   2:  /// Gets the (drag) source of cookies.
   3:  /// </summary>
   4:  /// <value>The source of cookies.</value>
   5:  public IDragSource SourceOfCookies
   6:  {
   7:      get
   8:      {
   9:          if (_source == null)
  10:              _source = new DragSource<CookieJar>(GetDragEffects, GetData);
  12:          return _source;
  13:      }

Handling the “Drop”

The drop operation is being handled in a similar fashion. This time however the attached property is of type IDropTarget and here’s how it is defined.

   1:  public interface IDropTarget
   2:  {
   3:      /// <summary>
   4:      /// Gets the effects.
   5:      /// </summary>
   6:      /// <param name="dataObject">The data object.</param>
   7:      /// <returns></returns>
   8:      DragDropEffects GetDropEffects(IDataObject dataObject);
  10:      /// <summary>
  11:      /// Drops the specified data object
  12:      /// </summary>
  13:      /// <param name="dataObject">The data object.</param>
  14:      void Drop(IDataObject dataObject);
  15:  }

Similarly the code in the DropTargetBehaviour class delegates the task of handling the data to the object implementing IDropTarget:

   1:  private static void Drop(object sender, DragEventArgs e)
   2:  {
   3:      var dropTarget = GetDropTarget((DependencyObject)sender);
   5:      dropTarget.Drop(e.Data);
   6:      e.Handled = true;
   7:  }
   9:  private static void DragOver(object sender, DragEventArgs e)
  10:  {
  11:      var dropTarget = GetDropTarget((DependencyObject)sender);
  13:      e.Effects = dropTarget.GetDropEffects(e.Data);
  14:      e.Handled = true;            
  15:  }

Putting it all together

To test the entire machinery I have developed a sample application which allows you to drag cookies between cookie jars. But there are constraints to it: you cannot drag anything out of an empty jar, and each jar will accept no mo re than ten cookies. These are the business rules which are enforced by corresponding unit tests.


The following fragment of XAML illustrates how the control is glued together with the DragSource and DropTarget behaviours:

<DragDrop:CookieJarControl Behaviours:DragSourceBehaviour.DragSource="{Binding SourceOfCookies}" 
                            Behaviours:DropTargetBehaviour.DropTarget="{Binding CookieSink}"

The source code for the entire project is available as part of the SharpFellows.Toolkit. As we develop more and more reusable goodies I am sure they will make it’s way into the library. Feel free to use it in any which way you want (this includes copy-pasting of suitable fragments) but please let us know if  you find it useful!

August 20 2010
Newer Posts Older Posts