Debugging design time data with MefedMVVM

 

Sometimes design time data just won’t show, even though everything works at runtime. This is quite normal since Expression Blend, and the Visual Studio designer for that matter don’t instantiate our views and ViewModels in the context of an application.

MefedMVVM has a concept of design time data using the IDesignTimeAware interface, so we can provide an implementation of our ViewModel purely for use by the designers.

In my current case, despite having all my bindings correct, and things working at runtime, Blend refuses to show me the design time ListBoxItems…

image

So like all things code-FAIL related, we debug, simply set a break point on the DesignTimeInitialization method and attach to Expression Blend.

image

You will need to close and re-open the Xaml View (or do a build) so Blend re-initialises our ViewModel… and viola! We now know what the problem is.

image

In my case it was simply a service which was missing at design time. Allowing defaults allows the design time composition to succeed since we don’t actually need it until runtime.

image

image

Much better!

Visual Studio Extensibility and MefedMVVM

 

Initially the project started out as a quick hack together to enable a single piece of functionality. However as functionality is growing its time for the codebase to grow up too, and this includes the UI elements. I’ve decided to use MefedMVVM for its design time blend features and easy to grok codebase.

If you try and use it out of the box with your MEF Component and debug, you might get the following error:

System.ComponentModel.Composition.ImportCardinalityMismatchException occurred
  Message=No valid exports were found that match the constraint '(((exportDefinition.ContractName == "RunOrDebugViewModel") etc…

Doh! Taking a look at the default runtime IComposer (what tells the container where to look for your assemblies) we can understand a little more of why it can’t find our assemblies.

private AggregateCatalog GetCatalog()
{
    var catalog = new AggregateCatalog();
    var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
    var extensionPath = String.Format(@"{0}\Extensions\", baseDirectory);
    catalog.Catalogs.Add(new DirectoryCatalog(baseDirectory));
    catalog.Catalogs.Add(new DirectoryCatalog(baseDirectory, "*.exe"));
    if (Directory.Exists(extensionPath))
        catalog.Catalogs.Add(new DirectoryCatalog(extensionPath));
    return catalog;

}

It’s basing the location from the current AppDomain, which makes perfect sense in a normal application, and infact should work with a deployed VSIX.

However when debugging a VSIX it resolves to:

"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\"

Odd, looking there my assemblies aren’t deployed there at all, debugging to find out where they actually are I can see:

“C:/Users/naeem.khedarun/AppData/Local/Microsoft/VisualStudio/10.0Exp/Extensions/Naeem Khedarun/NBehave/0.5.0.0/NBehave.VS2010.Plugin.Editor.dll”

I see, it’s actually deployed into the experimental instance of visual studio. Luckily for us, MefedMVVM does have a mechanism for us to override the default discovery logic.

So the first thing to do, is at whichever the first visual studio provider initialises first, we need to configure the MefedMVVM bootstrapper:

LocatorBootstrapper.ApplyComposer(new VisualStudioRuntimeComposer());

 

This will override the default runtime composer with our own, so lets implement the IComposer interface and tell it to look in the appropriate place…

public class VisualStudioRuntimeComposer : IComposer
{
    public ComposablePartCatalog InitializeContainer()
    {
        return GetCatalog();
    }

    public IEnumerable<ExportProvider> GetCustomExportProviders()
    {
        return null;
    }

    private AggregateCatalog GetCatalog()
    {
        var location = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
                             where assembly == typeof (ServiceRegistrar).Assembly
                             select assembly.Location).First();

        var directory = Path.GetDirectoryName(location);

        var catalog = new AggregateCatalog();
        catalog.Catalogs.Add(new DirectoryCatalog(directory));

        return catalog;
    }
}

 

We look in the current AppDomain as before, but this time look for our loaded assembly (one should be loaded or the bootstrapper wouldn’t have been called) and grabs its directory.

We can now resolve ViewModels in the experimental instance! I haven’t yet tried the new Composer with the normal instance, however if there are any issues I’ll make a follow up post.

An MVVM marquee control (in Silverlight and WPF)

Marquee controls have been around for a long time and have been abused for much of that time.  Their place in the user experience should really be very small, since they have a number of drawbacks – information isn’t static for the user to absorb, they typically only display a limited amount of information and they assume a certain reading speed (which may be too slow or too fast).  Nevertheless, there are times when marquee controls are useful, news or stock tickers for example.

So I needed a marquee to display a news ticker in Silverlight, and I didn’t want to have use any nasty code-behind.  Nothing seemed entirely appropriate, so I used the marquee control from Jobi Joy as a starting point and extended it:

  1. The control needed to work in an MVVM application.  This meant that it mustn't rely on code calling “ticker.StartAnimation()” or anything like that – it had to all work by binding to a view model.
  2. I changed the animation so that there is always as much content visible as possible, i.e. the first bit of content starts at the left-hand side, not at the right-hand side
  3. Just for kicks, I added a little bit of acceleration to the scrolling, so that it is not always a constant speed
  4. I got the marquee working in WPF as well as Silverlight

Some friends contributed here too – Marcin extracted the control template into generic.xaml, and Marlon fixed an issue where the marquee would zoom uncomfortably fast if there was too much content.  The result is that you can just use a few lines of XAML to achieve the effect:

<Controls:Marquee InitialPause="2"
                  FinalPause="2"
                  Duration="5"
                  Acceleration="0"
                  Height="20"
                  Grid.Row="0">
    <ItemsControl ItemsSource="{Binding Headlines}" ItemTemplate="{StaticResource HeadlineTemplate}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
</Controls:Marquee>

The control template for this uses a ScrollViewer to house a Canvas.  The content to be scrolled is placed on the canvas.

<ScrollViewer Width="Auto"
              Height="Auto"
              BorderThickness="0"
              HorizontalContentAlignment="Stretch"
              VerticalContentAlignment="Stretch"
              VerticalScrollBarVisibility="Disabled"
              Margin="0"
              Padding="0">
    <Canvas>
        <ContentPresenter x:Name="PART_Content"
                          VerticalAlignment="Center"
                          HorizontalAlignment="Center" />
    </Canvas>
</ScrollViewer>

An animation gets calculated and setup to scroll the content from right to left:

Storyboard _storyboard = new Storyboard();
DoubleAnimationUsingKeyFrames _animation = new DoubleAnimationUsingKeyFrames();

double totalDuration = InitialPause + Duration * _contentPart.ActualWidth / ActualWidth;
_animation.Duration = new Duration(TimeSpan.FromSeconds(totalDuration));

// _animation.KeyFrames setup omitted here for clarity. Get the source code if you want it.

_storyboard.Duration = new Duration(TimeSpan.FromSeconds(value + FinalPause));

if (_storyboard.Children.Count == 0)
{
    _storyboard.Children.Add(_animation);
    Storyboard.SetTargetProperty(_animation, new PropertyPath("(Canvas.Left)"));
    Storyboard.SetTarget(_animation, _contentPart);

    _storyboard.RepeatBehavior = RepeatBehavior.Forever;
}

_storyboard.Begin();

The result should show up below, if you have Silverlight 4 installed on your machine.

The full source code and samples in WPF and Silverlight can be found in the SharpFellows Toolkit.  And just for practice I used the Reactive Framework in the sample to asynchronously download and display some news headlines from a website.  Enjoy!

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);
  11:   
  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);
  18:   
  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;
  13:   
  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:      }
  31:   
  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:      }
  43:   
  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:      }
  52:   
  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.");
  61:   
  62:          IsBusy = true;
  63:   
  64:          _threadingService.QueueExecution(() => _executeMethod((T) parameter), CommandFinished, CommandError );
  65:      }
  66:   
  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;
  78:   
  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:      }
  86:   
  87:      private void CommandFinished()
  88:      {
  89:          _completionCallback();
  90:          IsBusy = false;
  91:      }
  92:   
  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.

image

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
Older Posts