Leveraging C# Partial Classes and Methods in Windows Universal Apps

There’s a number of ways we could implement platform specific code in Windows Universal Apps which I’ll cover in future articles.

In this article we’ll look at an often underused feature of C#: partial classes and methods.

Quick Overview

Partial classes allow us to split the definition of a class over multiple .cs files. The files all contain the same namespace and class names, but the class name is preceded by the partial keyword modifier.

Partial methods allow a method to be defined but that doesn’t contain an implementation, the implementation can then be provided in another partial class file.

(Check out my C# Tips eBook for more info on partial types.)

Using Simple Conditional Compilation Directives

If you want to get an overview of Universal Apps, check out this previous article.

For the sake of this demo, say we have a class “Identity” that displays a message box stating whether we’re in a Windows Store or Phone app.

We could do this using conditional directives:

using System;
using System.Threading.Tasks;
using Windows.UI.Popups;

namespace UsingPartials
{
    public class Identity
    {             
        public async Task WhoAmI()
        {
            string message = CalcMessage();

#if WINDOWS_APP

            message = "I'm a Windows Store App!";

#elif WINDOWS_PHONE_APP

            message = "I'm a Windows Phone App!";            

#endif

            var dialog = new MessageDialog(message);
            await dialog.ShowAsync();
        }
        
    }
}

And from a button click event handler in both the apps:

private async void WhoAmI_Click(object sender, RoutedEventArgs e)
{
    var id = new Identity();

    await id.WhoAmI();
}

Clicking the button in the apps results in the following message boxes being displayed:

image

 

image

 

Refactoring to Partial

So this is a simple example, but if there were lots of these conditional directives, we can tidy things up a little.

The idea is that the shared class “Identity” is made partial:

public partial class Identity

This class still contains the method that’s called from each of the apps, but this time the creation of the content of the message is delegated to a method called “CalcMessage”. This method sets the private field to be used in the dialog.

In the “Identity” class, the “CalcMessage” is declared as a partial method. This means that it doesn’t contain an implementation, but the “WhoAmI” method can still call it.

The actual implementation of the code that decides on the message is unique to the two apps.

So now the “Identity” class now looks like this:

using System;
using System.Threading.Tasks;
using Windows.UI.Popups;

namespace UsingPartials
{
    public partial class Identity
    {
        string _message;

        public async Task WhoAmI()
        {
            CalcMessage();

            var dialog = new MessageDialog(_message);
            await dialog.ShowAsync();
        }

        partial void CalcMessage();    
    }
}

We now create a new class file in the Windows Store app:

namespace UsingPartials
{
    public partial class Identity
    {
        partial void CalcMessage()
        {            
            _message = "I'm a Windows Store App!";
        }
    }
}

And another one in the Phone app:

namespace UsingPartials
{
    public partial class Identity
    {
        partial void CalcMessage()
        {
            _message = "I'm a Windows Phone App!";
        }
    }
}

Now the implementation of CalcMessage can be different for both platforms, but other code can still be shared in the shared project version of Identity.cs.

We also now don’t have any conditional directives in use.

If we only have one or two of these conditional directives, then it’s probably easier to just keep them as is, but if there are lots of them and it’s making readability harder then partials may be a useful alternative.

Getting Started Building a Universal Windows App

Universal Windows apps promise to enable the sharing of app code between Windows 8.1 Store apps and Windows Phone 8.1 apps.

In this demo, we’ll create a simple app and see how much work we can share between the two platforms. The sample code and design is probably not how we’d choose to implement a final solution but it will suffice for demo purposes.

Getting Started

Install Visual Studio 2013 Update 2.

Create a new project, head to the Visual C#, Store Apps, Universal Apps; choose the Blank App (Universal Apps) as the following screenshot shows. Name the app “Speechless”.

Visual Studio Universal App Create New Project

Once the solution is created, there will be 3 projects, one for Windows Store, one for Windows Phone, and a third project where we can put all the code we want to share between the two apps.

Universal App Solution

Creating a Shared Class

First off let’s create a class that we can share between apps:

solution screenshot

using System.Collections.Generic;

namespace Speechless
{
    static class Messages
    {
        public static IEnumerable<string> Greetings
        {
            get
            {
                yield return "Hello";
                yield return "Yo!";
                yield return "What's up?";
                yield return "Good day sir!";
            }
        }
    }
}

This just gives a few greetings that the user can choose from. Because this class was added in the Speechless.Shared project, it can be used from both apps.

So we could just go and create some XAML in each app and use this class, but let’s see if we can actually share XAML between apps to further reduce effort.

Creating a shared User Control

In the Speechless.Shared project, add a new item of type User Control called “ChooseGreatingControl.xaml”.

Add some XAML:

<UserControl
    x:Class="Speechless.ChooseGreatingControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Speechless"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400"    
    Width="300">
    
    <Grid>
        <StackPanel>
            <ComboBox Name="GreetingChoice" ></ComboBox>
            <Button Name="SayIt" Click="SayIt_OnClick">Speak</Button>
        </StackPanel>
    </Grid>
</UserControl>

This gives the user a ComboBox to choose which greeting to speak.

In the code behind:

using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace Speechless
{
    public sealed partial class ChooseGreatingControl : UserControl
    {
        public ChooseGreatingControl()
        {
            this.InitializeComponent();

            GreetingChoice.ItemsSource = Messages.Greetings;

            GreetingChoice.SelectedIndex = 0;
        }

        private async void SayIt_OnClick(object sender, RoutedEventArgs e)
        {
        }
    }
}

Here we’re just wiring up the ComboBox items to those in the Messages class and setting the default selected item to the first one.

Next let’s try to add some code to do some text to speech:

private async void SayIt_OnClick(object sender, RoutedEventArgs e)
{
    var sayWhat = GreetingChoice.SelectedValue as string;

    var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();

    Windows.Media.SpeechSynthesis.SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync(sayWhat);

    var mediaElement = new MediaElement();
    mediaElement.SetSource(stream, stream.ContentType);
    mediaElement.Play();
}

So now we have some UI XAML and some code, let’s see how easy it is to share this user control between the two apps.

Using the Same User Control from Both Windows Store and Windows Phone Apps

In the MainPage.xaml of the Windows Store app project, let’s add an instance of the user control:

<Page
    x:Class="Speechless.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Speechless"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <local:ChooseGreatingControl></local:ChooseGreatingControl>
    </Grid>
</Page>

Let’s go and do the same for the Windows Phone app:

<Page
    x:Class="Speechless.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Speechless"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <local:ChooseGreatingControl></local:ChooseGreatingControl>
    </Grid>
</Page>

Running the Apps

So lets try running now, first the Windows Store app (which is selected as the default start-up app), so F5…

Windows Store app screenshot

Clicking the Speak button works, and speaks outputs the selected greeting.

So let’s try the Windows Phone app, select it as the start-up app and hit F5…

System.UnauthorizedAccessException

This is because we need to add the Microphone capability to the Windows Phone app, once this is done the app runs and works as expected:

Windows Phone screenshot

Conclusions?

This is pretty cool. Having written an app in the past  that targets both Windows Store and Windows Phone this shared project makes things SO much easier – no linked file frustrations.

The next app I start writing (whether Store or Phone) I’ll use this Universal template just so if I want to port it to the other platform it will be ready to go.

It’s going to be interesting mixing this approach with Portable Class Libraries as well. Also a framework such as MVVMLight.

If there is code in the Shared project that only applies to either Store or Phone, we can use the predefined directives:

#if WINDOWS_APP
            // Store only app specific code here
#else
            // Phone only app specific code here
#endif

Whilst I don’t know what the plans are regarding Xbox One, it would be cool to have an Xbox One app store and we could just add an “Xbox One App” to our Universal Apps solution, build, and have the same app with most of the code and UI shared between Windows Store, Windows Phone, and Xbox One.

Exciting times!

Beyond the Compiler with ConventionTests

We often have conventions in our code. For example all DTOs/entity/etc. classes should be in a specific namespace, or the name of certain types of class should end with a given word. Another example, we may need to make sure that all classes (or those in a specific namespace) contain all-virtual members.

These kind of things are conventions that the team may agree to but the compiler won’t pick up as build errors or warnings. The code may still be completely valid C# even though it violates a convention.

ConventionTests is a brilliant idea (and it’s ideas like this that keep me loving programming) allows us to write tests to verify these conventions, conventions that the compiler cannot verify.

Installation

Simple installation via NuGet into your test project: PM> Install-Package TestStack.ConventionTests

Simple Usage

Using whatever testing framework you prefer (xUnit.net, NUnit, etc.) create a test method.

these kind of things are conventions that the team may agree to but the compiler won’t pick up

In this method, the first thing to do is to select all the types in the production code that we want to check against a convention.

We can do this with code such as:

var typesToCheck = Types.InAssemblyOf<SomeClass>();   

Here the Types.InAssemblyOf method is being used to find which assembly contains the class called SomeClass. Using this overload, all of the types in the assembly will be selected, however there are other overloads that allow the returning of types in a given namespace.

The next step is to create an instance of one of the out-of-the-box conventions.

var convention = new AllClassesHaveDefaultConstructor();

This convention checks that all the selected types have a default constructor defined.

Now we have the list of types we want to check, and a convention to check them against.

To actually perform the check, we use the Convention.Is method:

Convention.Is(convention, typesToCheck);

If any of the classes selected in typesToCheck don’t have a default constructor then an exception will be thrown (with some useful info in it) and the test will fail.

You can see some of the other out-of-the-box conventions on the GitHub site, you can also write your own custom conventions.

 

ConventionTests is one of the tools in the TestStack suite. To learn more about ConventionTests and the other TestStack tools, checkout out my Building the Right Thing in .NET with TestStack Plurasight course.

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.

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.

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...

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 :)

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...

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...