Downloading the session recordings from BUILD Windows 2011

I’ve updated the previous session downloader, originally published by Naeem and Marcin, to download the sessions from BUILD Windows 2011.  It will give you the option to download only the sessions that have video published, so you’ll need to keep checking it over the next few days as sessions get published.

Build session downloader

The app will run up to two concurrent downloads, and will queue up further requests.  So you can tell it the list of videos you want, and leave it to do it’s thing.  Downloads can be cancelled.

Note that it’s the High Quality WMV that will get downloaded.

You can get the source code at from Bitbucket, or you can download some pre-compiled binaries (.Net 3.5 required) or you can now get it using clickonce here.  Please let me know if you have any trouble with it.

UPDATE: Forgot to mention, as with the previous downloader this app supports resuming of partially completed download.

September 16 2011

WPF Toolkit ported to .Net 4.0 and VS 2010

Today I needed to make use of the WPF Toolkit from Codeplex in a .Net 4.0 WPF application.  Those who have used the WPF Toolkit will know that it was built for .Net 3.5 WPF, and a number of features within the toolkit got folded into the .Net 4.0 WPF framework (most notably a DataGrid control and the VisualStateManager).

Unfortunately the fact that these features got folded into WPF itself means that there a number of naming clashes between the toolkit and WPF 4.  This has been reported on the forums a few times and there is also a thread in which someone from MS China states “the WPF Toolkit will not be updated to 4.0 anytime soon”.

I really needed to use the charting controls from the toolkit and I didn’t want to deal with naming conflicts, so I forked the WPF Toolkit from Codeplex into a Bitbucket repo, upgraded it to .Net 4.0 and VS 2010 and removed all the bits which conflict with WPF 4.  The following have been removed:

  • VisualStateManager
  • DataGrid
  • Calendar
  • DatePicker

I have also dropped out the Visual Studio design-time support.  You can grab the code or the compiled assemblies from Bitbucket.

Enjoy!

July 21 2011

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!

Architecting UI plug-ins for PRISM applications

It often happens that a particular feature of an application is not used very often, but when you need it you would like it to be accessible easily and without hassle: think calculator in an order entry program. Surely the user can live without it and use the calculator provided with the OS, but what if he could access a simple calculator within a click or two inside the application itself? I could give you more examples like this, but they all fall under the same umbrella of add-ons or plug-ins. Things you surely could live without but having them handy makes the work so much easier.

As it happens I have recently built similar functionality into a PRISM application and the rest of the post describes how to do it in a (hopefully) more less generic fashion.

The plan

I envisioned a plug-in to be  visual “gadget” which the user could access through a window hosting all the plug-ins available in an application in a fashion similar to Visual Studio’s Toolbox. The important thing here is the fact that each plug-in would need to provide it’s own UI: at the end of the day the application cannot up-front provide UI for plug-ins which have not yet been written. Given these requirement I came up with the following plan:

  1. The application’s main window would provide screen estate for displaying all the plug-ins in form of a PRISM’s view region
  2. The plug-ins view region would be filled by a PluginsView containing an ItemsControl which would wrap each individual plug-in into expander
  3. Underlying View Model would simply expose a collection of IPlugin elements which could be bound to the view’s item control

The Plugin

Each of the plug-ins is required to implement IPlugin interface which first of all allows it to be discovered by the PluginHost and secondly forces the plug-in to expose a “View” of sorts which can be displayed to the user. As we’re in the PRISM world here, I would expect the View to be also injected into plug-in, but it is not strictly speaking required. Each plug-in also needs to provide user readable name which will be displayed in the UI.

/// <summary>
/// Common interface for all plugins
/// </summary>
public interface IPlugin
{
    /// <summary>
    /// Gets the name of the plugin.
    /// </summary>
    /// <value>The name.</value>
    string Name { get;  }

    /// <summary>
    /// Gets the UI representation of the plugin.
    /// </summary>
    /// <value>The view.</value>
    object View { get; }
}

All the plug-ins need to be registered with the IoC container and this, in case of PRISM applications is usually done during module initialization. One thing which has to be kept in mind in such case is to give unique “key” (name) to each plug-in during registration as there will be more than one implementation of IPlugin available:

public class PluginsModule : IModule
{
    private readonly IUnityContainer _unityContainer;

    public PluginsModule(IUnityContainer unityContainer)
    {
        _unityContainer = unityContainer;
    }

    public void Initialize()
    {
        _unityContainer.RegisterType<ICalculatorPluginView, CalculatorPluginView>();
        _unityContainer.RegisterType<INewsPluginView, NewsPluginView>();

        _unityContainer.RegisterType<IPlugin, CalculatorPlugin>("Calculator");
        _unityContainer.RegisterType<IPlugin, NewsPlugin>("News");
    }
}

 

The PluginHost

The role of the plug-in host is to simply consume all the implementations of IPlugin available in the application and expose them in a single collection. The simplest way to achieve that is to get them injected into the host by an IoC container. I was toying with the idea of using MEF for this purpose but at the end of the day settled for simplicity  and decided that Unity which is anyway used by PRISM will do the job as well. The following code fragment shows the inner workings of the host. As you can see the constructor gets all the implementations of IPlugin as an array which may seem a bit awkward, but this is what Unity expects out of the box. Having said that it is possible to inject an IEnumerable<IPlugin> which would seem more natural but it requires extra parameter when it comes to registering of the PluginHost with the container.

/// <summary>
/// Hosts all the plugins in the application
/// </summary>
public class PluginHost
{
    private readonly IPluginHostView _view;
    private readonly IPlugin[] _plugins;

    /// <summary>
    /// Initializes a new instance of the <see cref="PluginHost"/> class.
    /// </summary>
    /// <param name="view">The view.</param>
    /// <param name="plugins">The plugins.</param>
    public PluginHost(IPluginHostView view, IPlugin[] plugins)
    {
        _view = view;
        _plugins = plugins;
        _view.DataContext = this;
    }

    public IPluginHostView View
    {
        get { return _view; }
    }

    /// <summary>
    /// Gets the list of all the plugins available.
    /// </summary>
    /// <value>The plugins.</value>
    public IEnumerable<IPlugin> Plugins
    {
        get
        {
            return _plugins;
        }
    }
}

The PluginHostView

The purpose of the view is to show all the available plug-ins, each with his own specific UI. There is nothing magical about it apart from the fact that the item control uses item template which in turn uses plugin-provided UI as a content for the expander. I settled for the expander as I wanted to allow the user to collapse or expand them as and when required.

<Grid>
    <ItemsControl ItemsSource="{Binding Plugins}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Expander Margin="5,5,5,0"
                          Header="{Binding Name}"
                          Content="{Binding View}" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

 

Implementing a plug-in

Now given all the groundwork implementing a plug-in is a doodle. The code is fundamentally no different to any other view/view-model combo as the sample below illustrates:

public class NewsPlugin : IPlugin
{
    private readonly INewsPluginView _view;

    public NewsPlugin(INewsPluginView view)
    {
        _view = view;
        _view.DataContext = this;
    }

    /// <summary>
    /// Gets the name of the plugin.
    /// </summary>
    /// <value>The name.</value>
    public string Name
    {
        get { return "Latest News"; }
    }

    /// <summary>
    /// Gets the UI representation of the plugin.
    /// </summary>
    /// <value>The view.</value>
    public object View
    {
        get { return _view;  }
    }

    /// <summary>
    /// Gets the news.
    /// </summary>
    /// <value>The news.</value>
    public IEnumerable<string> News
    {
        get
        {
            return new[]
                       {
                           "Frogs Invade Pratt's Bottom...",
                           "Developer's bonuses set to triple in 2012",
                           "Read more..."
                       };
        }
    }
}

 

Wrapping it all up

The attached sample application illustrates how all the parts interact together. The full source code can be found here.

image

October 19 2010
Older Posts