Sunday, January 16, 2011

WPF Events to Command redirection using System.Windows.Interactivity

As mentioned previously, I recently used System.Windows.Interactivity library to make a command respond to an event on WPF controls without using any code-behind. In this post, I would give a brief overview and show some code on how to do it. I will try and keep the post to the point and not write anything about hooking up events with code or anything like that. Usual disclaimer applies – I am not entirely familiar with the internals but I know how to make it work and why it works.

So lets start with my simple requirement. I have a text box and as I enter I want to fire a command which processes the text and displays it on a textblock. Of course you can hook up both the controls to the same property in the ViewModel and with .NET 4.0 you can be sure that the getter will fire again when NotifyPropertyChanged is fired. But that is not the point here.

My XAML would simply have a textbox and a textblock. On textbox.TextChanged event fired, I would like to execute a command in my view model. The XAML is shown below.

<UserControl x:Class="Buddi.Training.Advanced.Interactivity.EventToCommandDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Buddi.Training.Infra"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
<Grid Background="Beige">
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<TextBox Text="{Binding SampleCommandParam,UpdateSourceTrigger=PropertyChanged}" Margin="20">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<local:EventToCommand Command="{Binding SampleCommand}"
CommandParameter="{Binding SampleCommandParam}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<TextBlock Text="{Binding Message}" Grid.Row="1" Padding="30" FontFamily="Consolas" FontWeight="14"/>
</Grid>
</UserControl>


You need to see how I am hooking up the event to the command in viewmodel which is the DataContext of the View (UserControl to be precise). Lets disect what we have here - We add an event trigger to the TriggersCollection on the Grid using the Interactivity.Triggers attached properties. An event trigger comes with the System.Windows.Interactivity.dll assembly. So add a reference to that library using the "Add Reference" dialog. The Event Trigger then expects an action that can be anything that derives from the TriggerAction<FrameworkElement> class. The TriggerAction derived class should implement one method called "InvokeCommand(object parameter)". The implementation simply takes care of executing the command which are passed to the DependencyProperty we defined in the EventToCommand class. Note that TriggerAction is a DependencyObject, thereby it allows you define Dependency Properties to take full advantage of the Binding, Styles, Animations and what not. So the trigger action is simple - (the following is a special implementation where I handle RoutedCommand different than the others, this is just my scenario and is typically bad - you are programming to the implementation which is not a good idea, but the plan here is to show how you can use the base.AssociatedObject).


namespace Buddi.Training.Infra
{
public class EventToCommand : TriggerAction<FrameworkElement>
{
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}

public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(ICommand), typeof(EventToCommand), new UIPropertyMetadata(null));




public object CommandParameter
{
get { return (object)GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}

// Using a DependencyProperty as the backing store for CommandParameter. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.Register("CommandParameter", typeof(object), typeof(EventToCommand), new UIPropertyMetadata(null));



protected override void Invoke(object parameter)
{
if (Command == null) return;
if (Command is RoutedCommand)
{
var rc = Command as RoutedCommand;
if (rc.CanExecute(CommandParameter, base.AssociatedObject))
{
rc.Execute(CommandParameter, base.AssociatedObject);
}
}
else
{
if (Command.CanExecute(CommandParameter))
Command.Execute(CommandParameter);
}
}
}
}


That's it! you can now program to the events using the commands that you already have. This lets you keep your code-behind clean and write more testable code than ever. I hope this is useful inspite of it not being the best of the articles. By the way, almost every MVVM framework out there provides an implementation of Event To Command action -eg : Caliburn, Cinch, you name it ... but not always it is possible for us to use a third party framework just for this one reason. In such cases, I thought it is good to know that you can acheive it just by using Microsoft's assembly.

Saturday, January 15, 2011

Working (around) with MSpecs

I just started playing with Machine.Specifications (MSpecs). Overall I am very satisfied with the project but I did ran across some issues - dont get me wrong, it works great but it was more like limitations because I was lame and using Express edition.
My specs are simple - I am trying to create a Dependency Injection Container that does absolutely very little, not as powerful as Unity or any other containers. I dont plan to use it anywhere - just am trying to create one for fun. So the specifications are simple (for now).
 
Mapping Interface to Type, MappingInterfaceToType
  » should allow creating instance of type registered
  
  In case of multiple constructors, pick the one with injection attribute, MultipleConstructorScenario
  » should create instance whose Value property is 20
  
  Container should support singleton instances, SingletonScenario
  » should return the same instance for every invocation
  
  Inner container should be supported, SupportForInnerContainer
  » should return registration from parent and itself


Simple right? Those are the output for my specifications. It it still under works but the output itself explains a lot - thats the power of the MSpecs. Business Analysts write requirements, gives specifications - This can be changed - they give us the requirements and we "program" the specifications. I know it appears to be some rewired Unit Testing, but if unit tests can give me a bunch of specifications and tell me what failed, I would be more than happy to use that.


Now lets write a specification from scratch. Look at the following simple C# code.
 public class Singleton { }
        public class Transient
        {
            public Singleton SingletonInstance { get; private set; }
            public Transient(Singleton ins)
            {
                SingletonInstance = ins;
            }
        }

I would like to register the Singleton class as - singleton and the transient class as - transient. So my specification is, instances of transient whose dependency is a singleton should get the same instance. So that becomes my "Subject"


[Subject("instances of transient whose dependency is a singleton should get the same instance.")]
public class InjectionOfSingletonForTransientResolution
{
}

Now to verify that specification, I need to "establish a context" which is that I need my container to be ready for use.
 Establish context = () =>
 {
            _builder = new TypeBuilder();
 };

Now that context is established, I will just write my specification. I create two instances and both my instances should have the same instance of Singleton.
It Should_Use_The_Same_Instance_when_creating_dependent_Components = () =>
{
            var instance1 = _builder.Resolve();
            var instance2 = _builder.Resolve();
            instance1.ShouldNotEqual(instance2);
            instance1.SingletonInstance.ShouldNotBeNull();
            instance2.SingletonInstance.ShouldNotBeNull();
            instance1.SingletonInstance.ShouldEqual(instance2.SingletonInstance);
};

But you know this would not happen just like that. I have my context and I know what it should do. I need to tell it why it should do that - that specification would pass "because I am registering dependency as singleton and instance as transient". So I add my reasons on why (or when) the specification would pass.
Because I_Am_Making_A_Dependency_Registration_As_Singleton_And_TestSubject_As_Transient = () =>
{
            _builder.Register(new Singleton());
            _builder.Register();
};

The whole specification would look like shown below.
[Subject("instances of transient whose dependency is a singleton should get the same instance.")]
    public class InjectionOfSingletonForTransientResolution
    {
        static ITypeBuilder _builder;

        public class Singleton { }
        public class Transient
        {
            public Singleton SingletonInstance { get; private set; }
            public Transient(Singleton ins)
            {
                SingletonInstance = ins;
            }
        }

        Establish context = () =>
        {
            _builder = new TypeBuilder();
        };

        Because I_Am_Making_A_Dependency_Registration_As_Singleton_And_TestSubject_As_Transient = 
        () =>
        {
            _builder.Register(new Singleton());
            _builder.Register();
        };

        It Should_Use_The_Same_Instance_when_creating_dependent_Components = () =>
        {
            var instance1 = _builder.Resolve();
            var instance2 = _builder.Resolve();
            instance1.ShouldNotEqual(instance2);
            instance1.SingletonInstance.ShouldNotBeNull();
            instance2.SingletonInstance.ShouldNotBeNull();
            instance1.SingletonInstance.ShouldEqual(instance2.SingletonInstance);
        };
    }

When I first run this my specification failed because my container does not handle that yet.
 instances of transient whose dependency is a singleton should get the same instance., InjectionOfSingletonForTransientResolution
  » Should Use The Same Instance when creating dependent Components (FAIL)
  Machine.Specifications.SpecificationException: Should be [not null] but is [null]
     at Machine.Specifications.ShouldExtensionMethods.ShouldNotBeNull(Object anObject) in d:\BuildAgent-03\work\38fe83de684fd902\Source\Machine.Specifications\ExtensionMethods.cs:line 181
     at Analytics.Specifications.Container.InjectionOfSingletonForTransientResolution.<.ctor>b__2() in C:\Users\bhargav\documents\visual studio 2010\Projects\Analytics\Analytics.Specifications\Container\TypeBuilderSpecs.cs:line 159
     at Machine.Specifications.Model.Specification.InvokeSpecificationField() in d:\BuildAgent-03\work\38fe83de684fd902\Source\Machine.Specifications\Model\Specification.cs:line 75
     at Machine.Specifications.Model.Specification.Verify() in d:\BuildAgent-03\work\38fe83de684fd902\Source\Machine.Specifications\Model\Specification.cs:line 53

I fix my container and now I see my specification pass.

One thing to remember is what ever you are working off - your context - it should be static - otherwise the compilation would fail. when looking at others examples, I had a similar question - so here I am telling you upfront.

Running specifications without leaving Visual Studio - No test runners are required.


All my specifications are in a separate class library. I would like to run the specifications without leaving Visual Studio (btw, I am using Express). I remember once upon a time I could make a class library as a startup project and somehow linked NUnit gui runner with the project. I could not get it done with VC# 2010 Express anymore. May be I am missing something. Anyway the solution was to add the following Post-Build event

image

Once my specifications project it built successfully, it automatically generates a nice output. You can use all command line arguments that mspec supports, for now I only care if they pass or fail, hence the simple one.

Debugging my specifications. It was painful


I tried all different strategies like using System.Diagnostics.Debugger.Break() and what not. ConsoleRunner that comes with mspec (mspec.exe) was crashing complaining that it encountered an user defined breakpoint in the code - yeah that was my intention. Anyway to work around that, I create a console program and in the console application, I added reference to my specifications library and from the Git Hub source code for the mspec.exe (thanks to OSS) the following C# code helped me overcome my limitation of not being able to use R# or TestDriven.Net.
 class ContainerSpecsRunner
    {
        static void Main(string[] args)
        {
            //Console.WriteLine(typeof(ITest).Assembly.Location);
            Program prog = new Program(new DefaultConsole());
            prog.Run(new[] { typeof(ITest).Assembly.Location });
        }
    }

ITest is a type that was defined in my specifications assembly. That way I need not worry about any arguments or hardcode path of my assembly. By the way, at work you might be killed for doing this, I am just doing it at my personal projects.

Some samples?


Ok the biggest problem I had was that I could not find some real world examples, the GIT HUB structure of the project was confusing as hell. I was hoping to find some examples, but I could not. As much as I like the project, I hate to see so little or almost non-existent guidance for new users. So here are some of my specifications. These are written by me - I am just learning the style of specs so forgive me if they are not what you wanted them to be. I am just trying to help.
public interface ITest{
    }

    public class Test: ITest{
        [Injector]
        public Test()
        {

        }
    }

    [Subject("Mapping Interface to Type")]
    public class MappingInterfaceToType
    {
        static ITypeBuilder _builder;

        Establish context = () =>
        {
            _builder = new TypeBuilder();
        };

        Because of = () =>
        {
            _builder.Register();
        };

        It should_allow_creating_instance_of_type_registered = () =>
        {
            var resolvedObject = _builder.Resolve();
            resolvedObject.ShouldNotBeNull();
            typeof(Test).ShouldEqual(resolvedObject.GetType()); 
        };
    }

    [Subject("In case of multiple constructors, pick the one with injection attribute")]
    public class MultipleConstructorScenario
    {
        public class Test2 : ITest
        {
            public int Value { get; private set; }
            public Test2(ITest demo)
            {
                Value = 10;
            }

            [Injector]
            public Test2()
            {
                Value = 20;
            }
        }

        static ITypeBuilder _builder;
        Establish context = () => {
            _builder = new TypeBuilder();
        };

        Because of = () =>
        {
            _builder.Register();
        };

        It should_create_instance_whose_Value_property_is_20 = ()=>
{
            var instance = _builder.Resolve();
            instance.ShouldBeOfType();
            (instance as Test2).Value.ShouldEqual(20);
        };
    }

    [Subject("Container should support singleton instances")]
    public class SingletonScenario
    {
        static ITypeBuilder _builder;

        Establish context = () =>
        {
            _builder = new TypeBuilder();
        };

        Because instance_Is_Registered = () =>
        {
            _builder.Register(()=>new Test());
        };

        It should_return_the_same_instance_for_every_invocation = () =>
        {
            _builder.Resolve().ShouldEqual(_builder.Resolve());
        };
    }

    [Subject("Inner container should be supported")]
    public class SupportForInnerContainer
    {
        static ITypeBuilder _builder;
        static ITypeBuilder _child;
        Establish context = () =>
        {
            _builder = new TypeBuilder();
            _child = _builder.CreateChildBuilder();
        };

        Because instance_is_registered_with_child_container = () =>
        {
            _builder.Register(new int[] { 0, 1, 2 });
            _child.Register();
        };

        It should_return_registration_from_parent_and_itself = () =>
        {
            var arr = (int[])_child.Resolve();
            arr.SequenceEqual(new[] { 0, 1, 2 }).ShouldBeTrue();
            _child.Resolve().ShouldBeOfType();
        };
    }


Would be nice if it can print my "Because" field names


Just like the console runner prints my "It" fields, it would be nicer if my reasons are printed. I will see if i can do that myself to the project and may contribute a little.


I hope the examples are useful. By no means they are perfect but they can get you started. You can see in the example I detailed in the beginning, I had a whole bunch of Should statements = that is plain wrong. Each specification should define one thing - otherwise it would be a big mess. Please look at this great project and I really am in love with MSpec.

Thursday, January 13, 2011

Executing RoutedCommand in Code-Behind

Recently I had this issue where we had a bunch of routed commands but those which were to be bound to an event instead of directly on a Button.Command. Anyway with all the event to command redirection (hint: use System.Windows.Interactivity EventTriggers and TriggerAction<FrameworkElement>), the requirement boiled down to executing a RoutedCommand in code behind.

Consider the command had a base class which looks as shown below.

public abstract class CommandBase
{
public ICommand Command { get; private set; }
public CommandBinding CommandBinding { get; private set; }
public CommandBase()
{
Command = new RoutedCommand();
CommandBinding = new CommandBinding(Command, HandlerExecute, HandlerCanExecute);
}

private void HandlerExecute(object sender, ExecutedRoutedEventArgs args)
{
Execute(args.Parameter);
}

private void HandlerCanExecute(object sender, CanExecuteRoutedEventArgs args)
{
args.CanExecute = CanExecute(args.Parameter);
}

protected abstract void Execute(object parameter);

protected abstract bool CanExecute(object parameter);

public static void DoCommandBind(CommandBase command, FrameworkElement element)
{
element.CommandBindings.Add(command.CommandBinding);
}
}

The base class simply provides everything that you need to make use of RoutedCommand. It wraps the command and its command binding whose execute and can execute handlers are redirected to the abstract methods. So the implementation would be as simple as the one shown below and you would have a full fledged RoutedCommand




public class SampleCommand : CommandBase
{
protected override void Execute(object parameter)
{
MessageBox.Show(parameter.ToString());
}

protected override bool CanExecute(object parameter)
{
return parameter != null;
}
}

In the above command, I simply execute the command if there is a parameter sent and when executed display the parameter passed in a MessageBox. In order to use this command in XAML, the markup would be as simple as :



<Button Command="{Binding Sample.Command}" CommandParameter="This is from XAML" Content="From XAML" />

But for the RoutedCommand to work, the CommandBinding associated with it should be added to one of the elements up in the Visual Tree. So one of the parents for the Button should have the CommandBinding for the command to be registered with them. This is performed using the CommandBase.DoCommandBind() method. This is required because - the RoutedCommand - even though it implements ICommand interface, the Execute() and CanExecute() methods simply trigger the events that result in the CommandBinding execute the handlers that were specified when the command binding was being created. Read on MSDN for a much better english explanation. If the command binding cannot be found on any of the ancestors, the command would never fire! This is important to understand when we later look at the C# way to execute a RoutedCommand.



For now, look at the code behind. It is simple and what happens in the constructor is self explanatory.




private CommandBase sample = new SampleCommand();

public CommandBase Sample
{
get { return sample; }
}

public CommandDemo()
{
InitializeComponent();
this.DataContext = this;
//do a command binding on this UserControl itself.
CommandBase.DoCommandBind(sample, this);
}


Gotcha 1 : RoutedCommand does not fire!


If this is the case, then make sure the CommandBinding for the RoutedCommand has been registered properly. You can do it in Code-Behind (like CommandBase.DoCommandBind() in my example) or in XAML (loads of examples online for that).



How do I execute a RoutedCommand from code-behind?


Again, same rules apply. The command binding should be available to be found on the ancestors where the command will be fired. If that is the case, then you can do it in the following way.




var rc = (sample.Command as RoutedCommand);
if (rc.CanExecute("This is command parameter", e.OriginalSource as Control))
rc.Execute("This is command parameter", e.OriginalSource as Control);


Executing the ICommand.Execute(parameter) (eg: sample.Command.Execute("parameter")) would work, but if in any case it does not work, use the method above.


Gotcha 2 : RoutedCommand.CanExecute(parameter) does not fire when executing a RoutedCommand from code-behind!


Yes, ICommand.CanExecute() is just an interface method, its the job the command invoker (if done in code-behind, it is you who is the command invoker) to verify if the command can be executed using CanExecute().



Well, thats all for now, I hope this helps some of us who were struggling with one place solution to execute RoutedCommands in code-behind. Hopefully, I will write one more brief article on using System.Windows.Interactivity.Triggers to redirect an event to a command, the MVVM way of executing actions.