Tuesday, January 25, 2011

Auto-ViewModel binding with Ninject

I have done a lot of post about binding ViewModels to Views in Silverlight, so can you see that it is really a subject I am quite interested in.  It also allows me to learn more about several technologies all in the context of this domain.

Having said this, lets have a look at using Ninject for Injecting our ViewModels into our Views.  We are going to use the concept of a ViewModelLocator that will be hosting our Ninject kernel in the application scope.

This means we are going to host our Locator as a resource in our App.xaml resource dictionary and bind to it in our views, using the StaticResource as a source.

You would go about doing this as following, and reference it in your code
<Application.Resources> 
<Foo:ViewModelLocator x:Key="viewModelLocator"/>
</Application.Resources>

<UserControl DataContext="{Binding [Bar], Source={StaticResource viewModelLocator}}"/>

You can see that we have defined our ViewModel with the name ‘Bar’ and within square brackets, this means we are binding to an indexer of the ViewModelLocator.  This allows us to do some pretty cool stuff, on the expense of loosing Intelli-Sense.
So lets get started on writing our locator, we first start my setting up our class and initializing some Ninject stuff, creating the Kernel, adding modules,…
public class ViewModelLocator
{       
private readonly IKernel kernel;       
public ViewModelLocator()
{           
kernel = new StandardKernel(GetModules());           
kernel.Load();       
}
}

So the really cool thing we can do now, is create an indexer that will allow us the query our ViewModels setup in our Kernel dynamically without having to type it, and add a new Property for every ViewModel.

The indexer is pretty straightforward, it looks like this :
public object this[string viewModel]
{
get { return GetViewModel(viewModel); }
}

So as you could imagine, the real stuff goes on in the GetViewModel method, so lets have a quick look at that now, I'll explain what we are doing here afterwards.
private object GetViewModel(string viewModel)
{
String viewModelName = viewModel;
if (!viewModel.ToUpper().EndsWith("VIEWMODEL"))
{
viewModelName = viewModelName + "ViewModel";
}
return kernel.Get(GetViewModelType(viewModelName));
}

private Type GetViewModelType(string viewModelname)
{
foreach (string location in GetLocations())
{
Type type = Type.GetType(string.Format("{0}.{1}", location, viewModelname), false, true);
if (type != null)
return type;
}
return null;
}

When we are calling our “Bar” viewmodel, the GetViewModel method will get a string with the value '”Bar”, from this it will need to locate the ViewModel from our kernel which could have a whole bunch of dependency’s injected ( or should I say nInjected ) into it.

Our locator will will take into account a few conventions, it will check the ViewModel string ends with “ViewModel” and if not will append it.  It will then attempt to find the ViewModel Type and return the corresponding instance of that type from the Ninject kernel.

This is where our last convention comes into play, our ViewModels in our application will most likely be located on some very well defined locations (hence the GetLocations method). We can easily define these conventions and possibly even add new ones later, a simple convention for locations might look something like this :
 private IEnumerable GetLocations()
{
string applicationNamespace = GetType().Namespace;
yield return applicationNamespace;
yield return applicationNamespace + ".Shared";
yield return applicationNamespace + ".Shared.ViewModel";
yield return applicationNamespace + ".Views";
yield return applicationNamespace + ".Views.ViewModel";
}

So this way you can add ViewModels with Ninject without having to define any properties to bind to, you just have to type your ViewModel’s name and the locator will do the rest for you.

Tuesday, October 19, 2010

Automatic MVVM Command Binding

When working with MVVM it can be quite a lot of work to wire up all commands with the view, bind them and make sure the right method was called.

Furthermore, you would need a property in your ViewModel that would bind to the view, wouldn’t it be nice to just have some methods in your ViewModel that would just like that respond to the buttons you click.

I came across this technique while looking at a MIX talk by Rob Eisenberg. The following example is an easy to use simple framework. It allows you to implement this quickly.  And use it without needing to change a lot of your already in place MVVM screens.  It is based on a great MVVM framework that Rob has been working on : Caliburn , which definitely is worth a look.

The concept that we are working with here, is to have some convention in our application in regards to using ViewModels and Commands.  The convention in this example is that all methods used for handling commands start with “Execute” and end with “Command”.  This is a very intuitive way to write commands, and is actually the way I was declaring then before I started to use this setup.

Lets say for a moment, we want to create new MVVM screen using a ViewModel, in this example we want to declare our ViewModel inside our View by calling an extension method “Bind<TViewModel>()” and binding the ViewModel to it.  You could eventually extract this into a Bootstrapper or so… But for now we will just keep it this way.

Our first class to do this, is our Extension class called “MvvmBindingExtension”.  It accepts a TViewModel generic type and reflects all Command methods in it.  Then it binds them to the View so they can be invoked.

Lets have a look at the implementation of this extension.

public static class MvvmBindingExtension
{
private const string COMMAND_METHOD_PREFIX = "Execute";
private const string COMMAND_METHOD_SUFFIX = "Command";

/// <summary>
/// Bind a ViewModel to a View, and auto bind commands
/// </summary>
/// <typeparam name="TViewModel">The ViewModel that should be </typeparam>
/// <param name="element">The view we want to bind our viewmodel to</param>
public static void Bind<TViewModel>(this FrameworkElement view) where TViewModel : new()
{
//Create an instance of our viewModel
object viewModel = new TViewModel();

//Get the type of the viewmodel for reflection purposes.
Type viewModelType = viewModel.GetType();

//Get all command methods obbeying the convention we set up for command handler methods
IEnumerable<MethodInfo> commandMethods = viewModelType.GetMethods()
.Where(method => method.Name.StartsWith(COMMAND_METHOD_PREFIX))
.Where(method => method.Name.EndsWith(COMMAND_METHOD_SUFFIX));

foreach (MethodInfo commandMethod in commandMethods)
{
//Make sure we get the right name of the method
int lengtOfSubString = commandMethod.Name.Length - COMMAND_METHOD_PREFIX.Length - COMMAND_METHOD_SUFFIX.Length;
string commandName = commandMethod.Name.Substring(COMMAND_METHOD_PREFIX.Length, lengtOfSubString);

//Get button by name
ButtonBase button = view.FindName(commandName) as ButtonBase;
if (button != null)
{
//Set binding to reflection command
button.SetBinding(ButtonBase.CommandProperty, new Binding { Source = new ReflectionCommand(commandMethod, viewModel) });
}
}
view.DataContext = viewModel;
}
}


You can see that we are using a “ReflectiveCommand” here,  this command takes the MethodInfo we have extracted from the ViewModel, and invokes it when executing the command on the ViewModel. 
We are binding this directly to the Source, so we don’t have to create any properties in our ViewModel to bind to.



public class ReflectionCommand : ICommand
{
private object target;
private MethodInfo method;

public ReflectionCommand(MethodInfo method, object target)
{
this.method = method;
this.target = target;
}

public bool CanExecute(object parameter)
{
return true;
}

public event EventHandler CanExecuteChanged;

public void Execute(object parameter)
{
method.Invoke(target, new[] { parameter });
}
}


This is command is then bound to a FrameworkElement that has the same name as the Command method without it’s PRE- and SUFFIX. So basically for a “Save” method this would be “ExecuteSaveCommand” where Save would then be set as the name of the element.



<Grid x:Name="LayoutRoot" Background="White">
<Button x:Name="Save" Content="Save"/>
</Grid>


Finally we would have a ViewModel that would look something like this, no more Command properties, no more RelayCommands being initialized. Just simply one public command method we can use.



  public class ViewModel
{
public void ExecuteSaveCommand(object parameter)
{
MessageBox.Show("Hello world!");
}
}

Monday, June 14, 2010

Useful Outlook Plug-in

If you are anything like me, you will have probably sent mails referring to an attachment without actually including the attachment in this mail.

So, anyone feel like this has happened to you, well here is some small tool that could prove useful.

To build it just create Outlook 2007 plug-in in Visual Studio, and add the following code.

public partial class ThisAddIn

   private Outlook.MailItem MailItem;

   private void ThisAddIn_Startup(object sender, System.EventArgs e)
   {
      this.Application.Inspectors.NewInspector +=   
      Inspectors_NewInspector;
   }

   void Inspectors_NewInspector(Inspector inspector)
   {

     Outlook.MailItem mailItem = inspector.CurrentItem 
     as Outlook.
MailItem;

     if (mailItem != null)
     {
       MailItem = mailItem;

       if (MailItem.EntryID == null)
       {
          ((
ItemEvents_10_Event)MailItem).Send += SendMail;
       } 
     }
   }

   private void SendMail(ref bool cancel)
   {

      if (MailItem.Attachments.Count == 0  && (MailItem.Body.ToLower()
          .Contains(
"attachment"))
      {
     
   if (MessageBox.Show("Are you sure you want to send this mail 
             without an attachment?"
, "Are you sure ?"
             MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==
              DialogResult.No)
             {
                cancel =
true;
             }
      }
   }  

   private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
   {
     ((ItemEvents_10_Event)MailItem).Send -= SendMail;
     this.Application.Inspectors.NewInspector –= Inspectors_NewInspector;

   }
}

 

So what exactly are we doing here ?

Basically it’s simply getting an inspector for a MailItem, and then intercepting the Send event.

A send event is triggered whenever a user clicks on send while creating an email.
Our code will simply check if this user has mentioned an attachment in his email and ask for confirmation to send this mail without any attachments.

Thursday, April 1, 2010

Tracking events with Rx in Silverlight

When you want to execute some code after multiple events have been completed, you don’t always know which event will be triggered first, you might have to synchronize them using some boiler plate logic.  This could, for example,  happen when you have to execute two service calls at the same time.

The solution for this problem comes with the Rx framework, the System.Reactive assembly found in the Silverlight Toolkit.

Image you have two events coming from “serviceProxy”, you could make them observable like this.

IObservable<Event<EventArgs>> observable1
    = Observable.FromEvent<RoutedEventArgs>(serviceProxy, "EventOne");

IObservable<Event<EventArgs>> observable2
    = Observable.FromEvent<EventArgs>(serviceProxy, "EventTwo");

You can execute the following Rx method to make sure only a composite event is triggered once both events have been triggered. 

IObservable<Event<EventArgs>> joinedObservable = observable1.ForkJoin(observable2);

To be able to now execute our event we can simply call the Subscribe method and execute a action of our choice :

joinedObservable.Subscribe( /* Some Method */ );

Thursday, February 25, 2010

Generating GUIDs with Powershell

Something I ran across the other day, was to use Powershell to generate a GUID.
This is quite useful since you’re not always working in a .NET application when you need one. And you don’t always want to compile an application to get it. 

One way to do this, is to talk to the .NET runtime in Powershell.  You can simply execute the following command :

[System.Guid]::NewGuid()

This will generate a simple Guid, however now you will still have to copy/paste it from your command line to be able to use it.
It would be very handy to immediately have the Guid available in your clipboard.

You can do this using the following powershell script :

[reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Windows.Forms.Clipboard]::SetText([System.Guid]::NewGuid().ToString())

This script will load the the Windows Forms assembly and get the Clipboard class to use the SetText method.  And … magic we have the Guid in our clipboard.

Tuesday, February 2, 2010

Silverlight : MEF and MVVM

With the upcoming release of Silverlight 4, I had a look at the Managed Extensibility Framework, since it is shipped together with Silverlight 4 once it is released.

What is MEF ?

According to the codeplex project :

MEF provides a standard way for the host application to expose itself and consume external extensions. Extensions, by their nature, can be reused amongst different applications. However, an extension could still be implemented in a way that is application-specific. Extensions themselves can depend on one another and MEF will make sure they are wired together in the correct order (another thing you won't have to worry about). 
source : http://mef.codeplex.com/

Basically you can export members of a class, these will be viewed by MEF as parts, which in turn can be imported by other classes.

When you want to import those parts to you Silverlight view you have to use, PartInitializer which will satisfy all imports on the class with the exported types.

MEF and MVVM

This functionality gave me the idea to import a ViewModel to a View to there is no link between the both in either direction. Allowing to easily change ViewModels and Views and reuse them.

Defining the contract

To be able to export and import our ViewModel parts, we have to define a contract for them.

We will simply add the following empty interface that we must implement on all our ViewModels :

public interface IViewModelBase { }

public class ViewModel : IViewModelBase
{
public string Value
{
   get
   {
     return "Some Display Value";
   }
}
}

Exporting our ViewModel

The next step would be to export our ViewModel and expose it so it can be imported by our view.

To do this we could provide a custom MetaModel class to make sure we can differentiate our ViewModels when assigning them to our View, however since we are only interested in a single identifier, we can create a custom export attribute to automatically do this.

To do this we first create a contract that will be implemented as the MetaData.

public interface IViewModelMetaData
{
string Identifier { get; }
}

Next we will create our custom export attribute, we should make sure we inherit the original ExportAttribute and mark the class as metadata so the metadata contract can be interpreted when we are importing.

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ViewModelExportAttribute : ExportAttribute, IViewModelMetaData
{
public ViewModelExportAttribute(): base(typeof(IViewModelBase))
{}

public string Identifier { get; set; }
}

We can apply this to our ViewModel by adding the following attribute above the class definition.

[ViewModelExport(Identifier = "MyViewModelIdentifier")]

Importing the ViewModel

At this point we want to be able to link the exported ViewModel to our View, to do this we can create a abstract class we can use as a base for all our views, implementing some basic functionality to enable the import.

public abstract class ViewBase : UserControl

   protected ViewBase() 
  
       PartInitializer.SatisfyImports(this); 
   }  

   public abstract string ViewModelIdentifier { get; }  

   [ImportMany
   public Lazy<IViewModelBase,IViewModelMetaData>[] ViewDataContext 
  
       set 
      
           DataContext = value
           .Where(viewModel => viewModel.Metadata.Identifier == ViewModelIdentifier)
           .First().Value; 
       
    }
}

So what exactly did we do here ?   To start ,we have created a ViewDataContext property of type Lazy<IViewModelBase,IViewModelData> and marked it with the ImportMany attribute.

Once the StatisfyImports method is called, MEF will initialize all properties marked with the Import attribute, in our case it will initialize the ‘ViewDataContext’ property.  Since MEF will import all Parts of the given IViewModelBase contract, we need a way to identify which ViewModel we want to use on our View, we can do this by exposing an abstract property ‘ViewModelIdentifier’ that will have to implemented by all views. 

Doing this we can check the exported metadata for the Identifier and compare it to the ViewModelIdentifier defined in the view, when a match has been found, the ViewModel is assigned to the DataContext of the view and we can do all the usual MVVM magic.

Monday, December 28, 2009

Creating a simple Commanding Framework for Silverlight 3

Whenever you are working with commanding, you are dependent on using either PRISM or perhaps the Interactivity framework. ( see my previous post )

Even in the future when Silverlight 4 is released there will only be support for commanding on Buttons and Hyperlinks.  So you might consider writing your own framework to handle all these things for you and allowing you to add some functionality on the way.

Getting Started

By default, Silverlight provides an ICommand interface that already provides you with a basic contract to get started with Commanding.  What we are going to do is extend this interface in an ITriggeredCommand interface. This will allow us to hook up some event handler when we want to execute the command.

public interface ITriggeredCommand : ICommand

     string Trigger { get; set; }
}

Setting up the Framework

Next we will create an abstract implementation to hide some of the contract from the ICommand and create our own contract.  We will however expose the possibility to invoke the CanExecuteChanged event, to be able to adapt our interface in the way we desire.

public abstract class BaseCommand<T> : ITriggeredCommand

    public string Trigger { get; set; } 

    private Action<T> execute;
    private Func<T, Boolean> canExecute; 

    public BaseCommand(Action<T> execute, Func<T, Boolean> canExecute)
    {
        if(execute == null)
            throw new ArgumentNullException("The execution action cannot be null.");
        this.execute = execute;
        this.canExecute = canExecute;
    } 

    /// <summary>
    /// When we have a canExecute function, execute it and pass the result
    /// </summary>
    public bool CanExecute(object parameter)
    {
        if (canExecute != null)
            return canExecute((T)parameter);
        return true;
    } 

    /// <summary>
    /// Execute the execution action, passing the parameter
    /// </summary>
    public void Execute(object parameter)
    {
        execute((T)parameter);
    }
    /// <summary>
    /// Allow for an implementation of this abstract class to invoke the CanExecuteChanged event
    /// </summary>
    protected void InvokeCanExecuteChanged()
    {
        if (CanExecuteChanged != null)
            CanExecuteChanged(this, EventArgs.Empty);
    } 

    public event EventHandler CanExecuteChanged;
}

At this point you should write a custom implementation of the BaseCommand<T>, however I will now continue with describing how we can hook this functionality up with our UI and ultimately allow you to use it in an MVVM application.

Making it work

So how do we hook up the commands to our UI,  well for this we can use attached properties and databind our commands to them accordingly.

The following code listing will describe how we can make sure the correct event is triggered ( the Trigger property ).

public static class Commands
{
    /// <summary>
    /// Register the new attached property for a command
    /// </summary>
    public static DependencyProperty CommandProperty = DependencyProperty.RegisterAttached
       (
           "Command",
           typeof(ITriggeredCommand),
           typeof(Commands),
           new PropertyMetadata(commandChanged)
       );  

   public static void SetCommand(DependencyObject obj, ITriggeredCommand propertyValue)
   {
       obj.SetValue(CommandProperty, propertyValue);
   } 

   public static ITriggeredCommand GetCommand(DependencyObject obj)
   {
       return (ITriggeredCommand)obj.GetValue(CommandProperty);
   } 

   //When the command changed make sure it is handled correctly 
   private static void commandChanged(DependencyObject obj, DependencyPropertyChangedEventArgs arguments)
   {
       if (arguments.NewValue is ITriggeredCommand)
       {
           ITriggeredCommand command = (ITriggeredCommand)arguments.NewValue;
           //Get the event that is related to the trigger
           EventInfo evInfo = obj.GetType().GetEvent(command.Trigger);
           //Create an eventhandler delegate for it
           Delegate executeEventDelegate = Delegate.CreateDelegate
               (
                  evInfo.EventHandlerType,
                   null,
                   typeof(Commands).GetMethod("handler",BindingFlags.Static | BindingFlags.NonPublic)
                );
            //Assign the Event handler to the object
            evInfo.AddEventHandler(obj,executeEventDelegate); 
        }
    } 

    //Execute the command
    private static void handler(object sender, EventArgs args)
    {
        ITriggeredCommand command = GetCommand((DependencyObject)sender);
        //We could implement an additional attached property to allow for a parameter to be set
        if (command.CanExecute(null))
            command.Execute(null);
    }
}

The important thing here is that we able to attach our command to an event that is related to the object we are binding our command to. 

In the commandChanged method we subscribe our handler to our event using reflection based on the EventHandlerType that was provided by the event defined in the Trigger property.