Simple RelayCommand using T4 Template

Simple RelayCommand using T4 Template

WPF is a great technology and it goes together well with MVVM pattern. You can code rapidly with them at hand, however there’s always something to improve. Commands are one of these things and now we’re going to take a look at what we can do about them with T4 Templates.

Recently I started a new side project in WPF and MVVM Light and created a few commands for buttons and events:

Nothing new, a standard way to do this. And it’s pretty fast to write when you use code snippets. Seems convenient, but when there is 3, 4 or more of them the code suddenly becomes cluttered. Why do I need so many lines for one command? Can’t it be simplified somehow? It would be great if instead of the code above I could just use this:

There is quite simple way to achieve this. Here’s what I did.

T4 Template

We need the code from the first snippet, but we don’t want to see it and we don’t want to write it by hand. We want it to be somewhere under the hood. All we need to do is to move RelayCommand to separate file and invoke our method in it.

Of course it should be automatic process. For this I used T4 Templates. With this great tool we can generate design-time code. You can read more about them on MSDN.

What exactly my template does?

  • It iterates through ViewModel directory in the project and searches for commands in all ViewModels (.cs files with file name ending in ViewModel – that’s probably pretty safe assumption) using Regex. The template .tt file should be put in the same folder as we need the path in the template. Commands are methods like in the second code snippet: public (or not), returning void and with Cmd at the end of the name. Method can take one parameter.
  • It creates new file for each ViewModel: adds usings, namespace, partial class and RelayCommands like in the 3rd snippet.

As I mentioned above, method has to end in Cmd so we can distinguish it from the rest. Binding in xaml stays the same. For example, in xaml we have binding to SimpleMethod and in ViewModel we create SimpleMethodCmd. T4 will create SimpleMethod RelayCommand for this binding.

T4 Template can actually have only one output file, but we can access generated output in code and save it to any file we want, just as described on this awesome blog by Oleg Sych.

There are three more things that we would need:

  • adding word “partial” to our ViewModel class – this is so simple that it can be done manually. In case we forget, VS will remind us during compilation.
  • adding files to the project
  • automatic run of T4 Template on build

Adding files to the project

When we use T4 Templates and we are good with default output file then there’s no problem, because it’s automatically added to the project. We could do that here too – keep all partial classes with RelayCommands in one file and don’t worry about this part, but I decided it will be better to organize it somehow and give each class a separate file. There are 3 ways of adding files to the Visual Studio project that I’m aware of:

  1. Wildcards in the project file. We can tell the project to include all the files in ViewModel folder by adding this line to .csproj:[xml]
    <Compile Include=”ViewModel\*.cs” />
    [/xml]It’s not perfect though as it may get removed when we make changes to that folder in Visual Studio.
  2. Another method involves using T4 Templates and it is described at the link above on Oleg Sych’s blog. It would be great automated way to add our generated files to the project, but we need some additional dependencies. If it’s not a problem then you can use it.
  3. The simplest way – adding files by hand. It’s not that bad when we look at the tools that Visual Studio gives us. We can right click ViewModel folder in Solution Explorer, open it and quickly drag & drop new files or do it even without leaving VS – with Show all files button.

We can also write our own utility for this task, but it could be overkill as new files will appear rather rarely. That’s why I decided to go with the 3rd route.

Auto run on build

Each time we save T4 Template it runs and output files are recreated. We could do that or we could run it on every build, depending on our needs. It is described here on MSDN how to do this easily, although we would need Visual Studio SDK for this. Another, even easier, way to do this is with nuget package named Clarius.TransformOnBuild created by Daniel Cazzulino. Here is his blog post with some details. Please note that .tt file Build Action should be set to None for this nuget package to work.

That’s pretty much it. That method should make viewmodels a little bit clearer. You can download my T4 template from this link. Just add it to your project and follow the steps above.