Write Less MVVM ViewModel Boilerplate Code with T4

Although code snippets can make creating our initial viewmodels easier (properties, commands,etc.) it’s still tantamount to boilerplate code. Obviously the actions that happen when a command is executed is not boilerplate, but the actual definition is.

T4 templates are built into Visual Studio and allow us to define templates that are a mix of literal output (such as HTML tags) and C# code.

We can for example create a C# for loop around some literal output, e.g. “Hello World” to output it 10 times. For more info on T4, check out MSDN.

T4 for View Model Code Generation

Rather than hand-coding viewmodels, we can define a T4 template. In this template we are able to define the view models we want generating – included both commands and properties that we want to have on those view models.

The implementation in this article creates a new abstract base class for each view model that contains our commands and properties, in addition to a command init method to create and wire-up new MVVM Light RelayCommands along with can execute hooks.

Once T4 has generated these base class view models, we inherit from them and a constructor that calls the base class’s InitCommands method.

The sample application bind some text and a button:

before clicking button

When you click the button the bound Person in the viewmodel is updated and the command is disabled:

after clicking button

 

The actual viewmodel code looks like this:

using SampleWpfApplication.Model;

namespace SampleWpfApplication.ViewModel
{
    class MainViewModel : MainViewModelBase
    {
        public MainViewModel()
        {
            InitCommands();
        }

        protected override void ExecuteLoad()
        {
            Who = new Person {Name="Jason"};
            LoadCommand.RaiseCanExecuteChanged();
        }

        protected override bool CanExecuteLoad()
        {
            return Who == null;
        }
    }
}

Note it derives from MainViewModelBase which is the generated code.

Also note there’s no Person property (called “Who”) and no RelayCommand defined.

We’ve overridden a couple of methods from the base class to get the behaviour we want and also called InitCommands in the constructor.

The fragment of the T4 template that defines the viewmodels looks like this:

/// <summary>
/// Make changes to this class to define what view models you want generating
/// </summary>
public  static class ViewModelGeneratorSettings
{   
    // ********** Which name space the view model classes will live in
    public const string OutputNameSpace = "SampleWpfApplication.ViewModel";


    public static List<ViewModelDefinition> ViewModelDefinitions
    {
        get
        {
            return new List<ViewModelDefinition>()
                   {
                       // Define your view models here
                       new ViewModelDefinition
                       {
                           Name = "MainViewModel",
                           Properties =
                           {
                               Tuple.Create("Who", "Person"), // here Who is the name of the command prop, Person is the type
                               //Tuple.Create("NextTopic", "Topic"),
                               //Tuple.Create("CurrentTopicTimeRemaining", "TimeSpan"),
                               //Tuple.Create("TotalTimeRemaining", "TimeSpan"),
                               //Tuple.Create("IsPlaying", "bool") // here IsPlaying is the name of the command prop, bool is the type
                           },
                           Commands =
                           {
                               "Load", // Name of the commands
                               //"Pause"
                           }
                       },
                       new ViewModelDefinition
                       {
                           Name = "AnotherViewModel",
                           Properties =
                           {
                               Tuple.Create("SomeProperty", "int"),
                           },
                           Commands =
                           {
                               "A",
                               "B"
                           }
                       }, // etc.
                   };
        }
    }
}

To create new viewmodels we just add new ViewModelDefinitions and specify what properties and commands we want – currently property types are specified as strings rather than actual types.

To get started and see it in action, download the sample application from GitHub and see how it fits together. The full template is here as well.

While the examples here relate to MVVM Light, the concept could be used with other frameworks.

SHARE:

Parsing Command Line Arguments with Command Line Parser Library

When writing .Net console applications we often need to parse command line arguments that the user specified when launching the application.

We get these arguments passed into the program in the args parameter of Main()

static void Main(string[] args)

If our application only has a single simple parameter then it’s probably ok to just parse it ourselves.

Once the number and type of parameters increase then there’s a whole host of complexity that can creep in:

  • What if values need converting to enum values?
  • How to handle arguments that takes a list of values?
  • How to implement verb style arguments like “git push”?
  • What if parameters are in different order?
  • What about optional parameters and should we use default values if they’re not supplied?
  • What about arguments that are mutually exclusive?

While we can program our console applications to account for these things it could be quite a lot of work and testing to implement effectively.

It makes sense in these cases to use a ready-built library such as Command Line Parser Library.

Command Line Parser Library Basics

This library represents arguments by creating a class and decorating its properties that represent args with the [Option] attribute.

class SomeOptions
{
    [Option('n', "name", Required=true)]
    public string Name { get; set; }

    [Option('a', "age")]
    public int Age { get; set; }
}

Here this class is stating that we should always have a name argument (Required=true) and we can specify it at the command line with the shorthand “-n” or longer --name”.

The age argument is optional and can be specified with “-a” or --age”.

So from the command line we could type:

myconsoleapplication.exe -n Jason --age 99

In our Main method we can now parse these arguments into  an instance of our SomeOptions class.

static void Main(string[] args)
{
    var options = new SomeOptions();

    CommandLine.Parser.Default.ParseArguments(args, options);

    // options.Name will = Jason
    // options.Age will = 99
}

The ParseArguments method takes the array of string args from the command line and populates our SomeOptions instance which we can then use in a strongly typed way.

There’s a lot more to this library such as implementing verb style arguments, strict parsing, and creating help text, all of which I cover in my Pluralsight Building .NET Console Applications in C# course.

SHARE:

Centralising RaiseCanExecuteChanged Logic in an MVVM Light Portable View Model

When working with an MVVM Light sometime we need to “tell” the view that a command’s ability to be executed has changed.

For example, when a user clicks a Start button to start a countdown, the Start button should be disabled and the pause button should then be enabled.

If we’re binding a button to an MVVM Light RelayCommand, the button will automatically disable when then RelayCommand’s CanExecute function returns false.

For this to work, when the user clicks Start, the command will execute, but then we need to tell the Start and Pause commands to raise their CanExecuteChanged events. To do this we can call the RaiseCanExecuteChanged method on each RelayCommand that logically makes sense for our application.

One approach is to put this in each property setter, for example:

public const string IsPlayingPropertyName = "IsPlaying";
protected  bool _isplaying;

public  bool IsPlaying
{
    get
    {
        return _isplaying;
    }

    set
    {
        if (_isplaying == value)
        {
            return;
        }

        RaisePropertyChanging(IsPlayingPropertyName);
        _isplaying = value;
        RaisePropertyChanged(IsPlayingPropertyName);
              
        // RAISE CANEXECUTECHANGED HERE IN PROP SETTER
        PauseCommand.RaiseCanExecuteChanged();
        StartCommand.RaiseCanExecuteChanged();
    }
}

Now when this IsPlaying property changes, the Pause and Start buttons commands can execute will be updated.

A problem with this approach is that the logic to decide which RelayCommands CanExecuteChanged event gets raised in response to which properties are changing is distributed through all the property setters in the ViewModel. This can make it hard to reason about the changes in state of the ViewModel.

One alternative approach is to centralise this logic in a single method.

More...

SHARE:

Portable Class Library (PCL) Timer when Targeting Both Windows 8 and Windows Phone using Reactive Extensions

Currently the Timer class is not available when targeting both Windows Phone 8 and Windows 8 Store Apps.

For the app I’m building I want the MVVMLight PCL ViewModel to update a property every second – the databound View then simply updates itself.

One solution is to implement your own Task based Timer as described in this Stack Overflow article.

Another approach could be to make use of Reactive Extensions Observable.Interval method to create a sequence that updates every n-seconds.

First off add the Reactive Extensions NuGet package to your PCL project.

Next, in the ViewModel constructor (or command, etc.) create the interval stream and then tell it to execute a method every second:

var timer = Observable.Interval(TimeSpan.FromSeconds(1)).DistinctUntilChanged();

timer.ObserveOn(SynchronizationContext.Current).Subscribe(TimerTick);

 

I’m using SynchronizationContext.Current because the TimerTick method (below) updates the ViewModel property, without this there is a thread access problem.

So the TimerTick method ends up being called every second and simply updates the (MVVMLight) TotalTimeLeft property:

private void TimerTick(long l)
{
    TotalTimeLeft = DateTime.Now.Second.ToString();
}

I’m not an expert on Rx so there may be a better way of using it in this instance (or some potential hidden problems) but it’s working in the app so far (and on ARM Surface RT)…

It’s however cool to know that Rx has portable class library support.

Any Rx experts feel free to comment on a better way :)

SHARE:

Telling a View to display a Message Dialog from the ViewModel With MVVMLight in Windows 8.1 Store Apps

The technique below is one technique, others exist, but the design goals of this approach are:

  1. The ViewModel cannot know or reference the View
  2. The ViewModel should should not care how the View displays or interacts with the user (it could be a dialog box, a flyout, etc.)
  3. The ViewModel must be Portable Class Library compatible and View agnostic, e.g. not need to know about dialog buttons, etc.
  4. Choices the user makes in the View dialog should result in Commands being executed on the ViewModel
  5. The ViewModel must not specify the content of the message text, button labels, etc. – the View should be responsible for the text/content of the message

One way to think about these design goals is that the ViewModel is asking for some semantic message/dialog to be displayed in the View.

Defining a Message to be used with the MVVM Light Messenger

The way the ViewModel “tells” the View to create a dialog is by sending a message using the MVVM Light Messenger.

First we define a custom message:

using System.Windows.Input;
using GalaSoft.MvvmLight.Messaging;

namespace Project.Portable.ViewModel.Messages
{
    public class ShowDialogMessage : MessageBase
    {
        public ICommand Yes { get; set; }
        public ICommand No { get; set; }
        public ICommand Cancel { get; set; }
    }
}

This message allows us to define the commands that the view will call, based on the choice that the user makes in the dialog.

More...

SHARE:

Handling CTRL-C in .NET Console Applications

By default, pressing CTRL-C while a console application is running will cause it to terminate.

If we want to prevent this we can set Console.TreatControlCAsInput Property to true. This will prevent CTRL-C from terminating the application. To terminate now, the user needs to close the console window or hit CTRL-BREAK instead of the more usual and well-known CTRL-C.

class Program
{
    private static void Main(string[] args)
    {
        Console.TreatControlCAsInput = true;
        while (true)
        {
        }
    }
}

There is also the Console.CancelKeyPress event. This event is fired whenever CTRL-C or CTRL-BREAK is pressed. It allows us to decide whether or not to terminate the application.

More...

SHARE:

Getting Input From Alternative Sources in .NET Console Applications

Using the Console.SetIn Method allows us to specify an alternative source (TextReader stream).

For example suppose we have the following “names.txt” text file:

Sarah
Amrit
Gentry
Jack

We can create a new stream that reads from this file whenever we perform a Console.ReadLine(). Now when we call ReadLine, a line is read from the text file rather than the keyboard.

We can use the Console.OpenStandardInput() method to reset input back to the keyboard.

The code below creates the following output:

More...

SHARE:

Creating a Spinner Animation in a Console Application in C#

If we have a longer running process taking place in a console application, it’s useful to be able to provide some feedback to the user so they know that the application hasn’t crashed. In a GUI application we’d use something like an animated progress bar or spinner. In a console application we can make use of the SetCursorPosition() method to keep the cursor in the same place while we output characters, to create a spinning animation.

consolespinner1

While the code below could certainly be improved, it illustrates the point:

More...

SHARE:

Setting Foreground and Background Colours in .NET Console Applications

In addition to doing some fun/weird/useful/annoying things in Console applications, we can also set foreground and background colours.

To set colours we use the Console.BackgroundColor and Console.ForegroundColor properties.

When we set these properties we supply a ConsoleColor. To reset the colours back to the defaults we can call the ResetColor() method.

using System;

namespace ConsoleColorDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Default initial color");

            Console.BackgroundColor = ConsoleColor.White;
            Console.ForegroundColor = ConsoleColor.Black;
            Console.WriteLine("Black on white");
            Console.WriteLine("Still black on white");

            Console.ResetColor();

            Console.WriteLine("Now back to defaults");

            Console.ReadLine();

        }
    }
}

The above code produces the following output:

More...

SHARE: