Thursday, September 22, 2011

Extending the Personalplaner

Every application should be extensible!
That's why I added the ability to create plugins for the Personalplaner. Well actually I did it mainly just for the fun of it...

To achieve this I used MEF. MEF started as a Codeplex project but now is fully integrated in the .NET Framework in the Assembly System.ComponentModel.Composition.

With the help of MEF it is realy easy to create and use plugins resp. export and import objects.
In my case I only had to create an Interface and implement this in the plugin class and add the class attribute [Export(typeof(IPlugin))] (IPlugin is the interface I created...)

[Export(typeof(IPlugin))]
public partial class PlanAnalysisPlugin : BaseControl, IPlugin
{
    ...
}


In the class that imports the plugins, I only needed to create a CompositionContainer that creates/imports the objects and a container that will containe the imported objects.

CompositionContainer _container;

//public IEnumerable<Lazy<IPlugin, IPluginMetadata>> Plugins
/// <summary>
/// Enumeration containing all loaded pluginsEnumeration containing all loaded plugins
/// </summary>
[ImportMany]
public IEnumerable<IPlugin> Plugins
{
    get;
    set;
}

private bool Compose()
{
    if (!Directory.Exists("plugins"))
        return false;

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

    _container = new CompositionContainer(catalog);

    try
    {
        this._container.ComposeParts(this);
    }
    catch (Exception)
    {
        return false;
    }

    return true;
}

In my case I decided to keep the plugins in the subfolder named plugins.


If the folder is empty then the application should look like this. On the left side there are only the options for Plan and About.


If I put my plugin into the folder plugins, the application should load and insert it in between Plan and About. In this case I created a plugin that shows some reports and displays some additional inforamation to the plans.


I know that I will most probably be the only person that will ever create a plugin or an extension for the Personalplaner. But with this I can easily extend the Personalplaner with new features without having to create a new version and a setup every time.

Monday, September 12, 2011

Animated loading screen

When loading big data collections or switching between views that contain a lot of data, there is often a big timespan where the user is not sure if the application has crashed or if it is doing something.
So I wanted to draw a semi transparent overlaying layer over the window and create an animation that indicates that the application is doing some work.

Sounds easy... In reality it's something that's almost impossible!

In wpf the UI thread is not the same as the main application thread. But still they are linked to each other so that the UI thread gets blocked when the main thread is working hard. With this restriction there can't be any semi transparent layer and especialy no animation that gets shown or executed while the main thread is working.

When I was about to give up I stumbled upon a grea thread by Dwayne Need describing how single elements in wpf can be run in a separate thread. This means some complicated threading and trying to get the data binding and the resizing of the controls syncronized between the different threads, but in the end I managed to get it all worked out.

Now I am able to display an animation while the main tread is doing some hard work trying to accomplish whatever tasks I let it do.



Wednesday, September 7, 2011

Print preview in Personalplaner 2.0

I implemented the new print dialog and the print preview for the Personalplaner.


I was not shure if I should create my own new implementation of a print dialog or use the default dialog, even though it doesn't suit my needs very well.
And how should I create the preview of the printout?

I decided to create my own version of a print dialog and implement the preview both in one...
And I like it!


On the left side the user can choos which teams and which columns of that should be printed and which printer to use.
The user has the possibility to preview all pages with the pageing at the bottom left of the preview image.

 For previewing the printout I developed a pageviewer, with paging ability and the preview completely new and all from scratch. If the window is smaller than the printout/pagesize, the pageviewer automaticaly scales the pages down so that the whole page is allways visible.

 I'm realy pleased with the result I got.