Tag Archives: MVVM

Unit Testing Methods With Random Elements (in MVVM Cross)

Okay, quick spoiler for this: you can’t. You can’t, not really; obviously, you can write the test, but unit tests should be predictive, and a random element should not.

Solution

I imagine there are a few ways of solving this. The way shown in this post is specific to MVVM cross, but should work with any system that uses an IoC container. In brief, we’re simply going to mock out the system Random class.

How?

Well, since System.Random is the domain of Microsoft, we’ll start with a wrapper; and since this is MVVM Cross, we’ll make it a service:

    class RandomService : IRandomService
    {
        private static Random _rnd = null;

        public virtual int SelectRandomNumber(int max)
        {
            if (_rnd == null)
            {
                _rnd = new Random();
            }

            return _rnd.Next(max);
        }
    }

Couple of notes on this:
1. I haven’t posted the interface but it’s just the one method.
2. The reason for the Random class being static is that the random seed is taken from the system clock, meaning that if you call this in quick succession, there is a possibility that you would get the same number returned.
3. This is not thread safe.

Okay – all that out of the way, the code is pretty basic. Now let’s call it:

        public static T SelectRandomElement<T>(this IEnumerable<T> enumeration)
        {
            var service = Mvx.Resolve<IRandomService>();            
            int idx = service.SelectRandomNumber(enumeration.Count() + 1);

            return enumeration.ElementAt(idx);
        }

Right, so you’ll recognise the extension method from the last post, but now it retrieves the instance of the random service; here’s where we register that:

        protected override void InitViewModel()
        {
            Mvx.ConstructAndRegisterSingleton<IRandomService, RandomService>();
        }

You can actually register it anywhere you like… before it’s actually called.

Okay, so now we should have unchanged functionality; everything works as before.

The Unit Tests

The first task here is to create the mock RNG:

    class MockRandomService : IRandomService
    {
        static int _lastNumber = 0;

        public int SelectRandomNumber(int max)
        {            
            if (_lastNumber < max)
                return ++_lastNumber;
            else
            {
                _lastNumber = 0;
                return _lastNumber;
            }                
        }
    }
&#91;/sourcecode&#93;

This not allows me to determine what the next random number will be.

<strong>MVVM Cross Unit Testing</strong>

To set-up a test for MVVM Cross using the IoC container, you need to add some additional libraries to the test project first:

<a href="http://pmichaels.net/wp-content/uploads/2014/07/mvvmtest.png"><img src="http://pmichaels.net/wp-content/uploads/2014/07/mvvmtest.png?w=300" alt="mvvmtest" width="300" height="32" class="alignnone size-medium wp-image-618" /></a>


This will add Cirrious.MccmCross.Test.Core:

<a href="http://pmichaels.net/wp-content/uploads/2014/07/refs.png"><img src="http://pmichaels.net/wp-content/uploads/2014/07/refs.png" alt="refs" width="239" height="211" class="alignnone size-full wp-image-620" /></a>

And that is important, because it allows you to declare your test class as follows:


    [TestClass]
    public class ExtensionMethodTests : MvxIoCSupportingTest
    {

Inheriting from MvxIoCSupportingTest allows you to call base.Setup(), which prevents the IoC container from crashing when you call it in a test. Here’s the full unit test code:

[TestClass]
public class ExtensionMethodTests : MvxIoCSupportingTest
{
[TestMethod]
public void TestSelectRandomElement()
{
base.Setup();

Mvx.ConstructAndRegisterSingleton();

List testCollection = new List();

testCollection.Add(1);
testCollection.Add(3);
testCollection.Add(5);
testCollection.Add(7);
testCollection.Add(9);

// Cycle through all elements
for (int i = 0; i <= 5; i++) { int e = testCollection.SelectRandomElement(); Assert.AreNotEqual(e, 0); } } [TestMethod] public void TestSelectRandomElementPredicate() { base.Setup(); Mvx.ConstructAndRegisterSingleton();

List testCollection = new List();

testCollection.Add(1);
testCollection.Add(3);
testCollection.Add(5);
testCollection.Add(7);
testCollection.Add(9);

// Cycle through all elements
for (int i = 0; i <= 5; i++) { int e = testCollection.SelectRandomElement(n => n < 2); Assert.AreNotEqual(e, 1); } } } } [/sourcecode] Conclusion

So, I now have a custom RNG and unit tests that will tell me what happens when I call the method for each element. Obviously these tests are not exhaustive, but they are deterministic.

Helpers and Extension Methods for Games

Typically, extension methods and helpers are small methods that allow the same functional code to be re-used. An excellent (and useful) example is this:

        public static void ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
        {
           foreach (T item in enumeration) action(item);
        }

The above extension method provides a `ForEach` method for `IEnumerable`.

Are games different?

Yes.

Because a method for a game may involve a random algorithm. Below are a collection of methods that I’ve found useful.

Helper Methods

I’ve put all the following methods in a class called Dice. Obviously, for the first method, the name only makes sense in the context of a Dice class.

        /// <summary>
        /// Returns a boolean denoting the result of a 1 in chance dice roll
        /// </summary>
        /// <param name="chance"></param>
        /// <returns></returns>
        public static bool Roll(int chance)
        {
            Random rnd = new Random();

            return rnd.Next(chance) == 1;
        }

I use this everywhere in my games:

If (Dice.Roll(10)) // character has a 1 in 10 chance of dying if they drink the potion

The next method is basically just a wrapper for Random.Next.

Tip: You may find the random algorithm works best if you maintain the `rnd` variable for the life of the game. The reason for this being the the default random seed is taken from the system clock. Consequently, calling the same method in rapid succession may result in the same number being returned.

        /// <summary>
        /// Select a random number
        /// </summary>
        /// <param name="max"></param>
        /// <returns></returns>
        public static int PickRandomNumber(int max)
        {
            if (max <= 0) return 0;

            Random rnd = new Random();
            return rnd.Next(max);
        }

    }
&#91;/sourcecode&#93;

The context for this would be to allocate a number, for example:

&#91;sourcecode langiage="csharp"&#93;
Character.Health = Dice.RickRandomNumber(10); // allocate character's initial health
&#91;/sourcecode&#93;


<strong>Extension Methods</strong>

The following methods allow you to return a random element from a collection; the second allows for a predicate before the element is selected.


    static class EnumerableExtensions
    {
        public static T SelectRandomElement<T>(this IEnumerable<T> enumeration)
        {
            Random rnd = new Random();
            int idx = rnd.Next(enumeration.Count());

            return enumeration.ElementAt(idx);
        }

        public static T SelectRandomElement<T>(this IEnumerable<T> enumeration, Func<T, bool> predicate)
        {
            var filteredList = new List<T>();
            enumeration.ForEach((item) => { if (predicate(item)) filteredList.Add(item); });

            Random rnd = new Random();
            int idx = rnd.Next(filteredList.Count());

            return filteredList.ElementAt(idx);
        }
    }

A typical usage for these would be:

var enemy = AllCharacters.SelectRandomElement(e => e.CharacterType == CharacterTypes.Enemy);

Unit Tests

The biggest problem with code like this, is that it’s difficult to unit test. For example:

[TestMethod]
public void TestSelectRandomElementPredicate()
{
List testCollection = new List();

testCollection.Add(1);
testCollection.Add(3);
testCollection.Add(5);
testCollection.Add(7);
testCollection.Add(9);

int e = testCollection.SelectRandomElement(n => n < 2); Assert.AreNotEqual(e, 1); e = testCollection.SelectRandomElement(n => n < 2); Assert.AreNotEqual(e, 1); [/sourcecode] Certainly, if the method is bug free, then this will always pass; however, there may be a bug that only ever occurs when the first or last element is chosen. In the next post I'll cover how to unit test methods with random elements.

MVVM Cross Basics – Passing Complex Parameters During Navigation

Having covered basic navigation, I found that I needed to pass my game state from view-model to view-model. I initially thought that I could simply do this as follows:

    private void CallVM2()
    {
        MyObj newObj = new MyObj();
        IMyService myService = new MyService();

		Dictionary<string, object> p = new Dictionary<string, object>()
        {
            {"MyObj", newObj},
            {"MyService", myService}
        };
		ShowViewModel<ViewModel2>(p);
    }

The code for ViewModel2:

    public void Init(Dictionary<string, object> p)
    {
    }

Anyway, it turns out you can’t. Init does get fired, but if you pass anything more complex than a string, it just bins the parameter.

The answer appears to be to create a class and to serialise it using JSON.NET:

http://stackoverflow.com/questions/19058173/passing-complex-navigation-parameters-with-mvvmcross-showviewmodel

After implementing this suggestion, I ended up with something like this:

    public abstract class BaseViewModel : MvxViewModel
    {
        private const string ParameterName = "parameter";

        public BaseViewModel()
        {
        }

        protected void ShowViewModel<TViewModel>(object parameter) where TViewModel : IMvxViewModel
        {
            var text = Mvx.Resolve<IMvxJsonConverter>().SerializeObject(parameter);
            base.ShowViewModel<TViewModel>(text);
        }

        public void Init(string parameter)
        {
            if (parameter == null || parameter.Length == 0) return;

            IMvxJsonConverter converter = Mvx.Resolve<IMvxJsonConverter>();
            NavigationParameter deserialized = converter.DeserializeObject<NavigationParameter>(parameter);
            RealInit(deserialized);
            
        }
    }

If you don’t register the converter in the IoC container (as I initially didn’t), then you’ll get this error:

A first chance exception of type ‘Cirrious.CrossCore.Exceptions.MvxIoCResolveException’ occurred in Cirrious.CrossCore.DLL

Additional information: Failed to resolve type Cirrious.CrossCore.Platform.IMvxJsonConverter

The fix:

    public abstract class BaseViewModel : MvxViewModel
    {
        private const string ParameterName = "parameter";

        public BaseViewModel()
        {
            Mvx.RegisterType<IMvxJsonConverter, MvxJsonConverter>();
        }

Now, if you override the `RealInit` method, you’ll see that the parameters are, indeed, available. However, I had a further problem; this time being with JSON.NET. As you can see from the above structure, it’s a dictionary of objects. So, when running this, it will certainly pass through the object, but it’ll just be the serialised string.

And…?

I’m pretty sure that I could get around this using a combination of generics and a custom Javascript serialisation library, but I’ve got a game to write, so I’m going to stick with declaring the Navigation parameter as follows:

   public class NavigationParameter
    {
        public MyObject ObjectParameter { get; set; }
        public MyService ServiceParameter { get; set; } 
    }

It’s worth bearing in mind that you can’t use interfaces either in the parameters; JSON.NET needs a concrete class.

MVVM Cross Basics – Navigating Using Commands

I’m quite new to MVVM Cross. I thought I’d start another series of posts on my progress (I haven’t forgotten about the others). Especially where I haven’t found as much documentation as I’d like. My latest project is a game written using the MVVM Cross framework; it’s not a shoot-em-up or an action game, but it will be a game. When it’s finished, I’ll post a link if I get it in any of the stores.

Quick Tips

So far, the best place to go if you’re new to MVVM Cross is Stuart Lodges videos:

https://www.youtube.com/watch?v=_DHDMNB_IeY

Stuart is also a regular of Stack Overflow.

Navigation

The way that MVVM Cross works is slightly different to what I would have expected, in that the ViewModel is the key to the navigation. The view is then determined using a naming convention. In this example, I’m starting the application in a ViewModel called Home, and navigating to Main. Home will display the “New Game / Continue Game” dialog, and Main will be the main game screen.

This blog post is not intended to show how to set-up a new MVVM Cross project; however, essentially my game architecture is as follows:

Game Solution
– Game.PCL
– Game.Windows
– Game.WindowsPhone (currently disabled as this doesn’t work)
– Game.Shared

I have no idea whether this will work, but I think it should. If it doesn’t then I’m sure there’ll be some useful lessons on the way.

MvxCommand – the ViewModel

There is a in-built command type called MvxCommand, and that is what I’m going to use. Here’s how I set-up my VM:

    public class HomeViewModel : BaseViewModel
    {
        private MvxCommand _startNewGameCommand;
        private MvxCommand _continueExistingGameCommand;

        public IMvxCommand StartNewGameCommand
        {
            get
            {
                return _startNewGameCommand;
            }
        }

        public IMvxCommand ContinueExistingGameCommand
        {
            get
            {
                return _continueExistingGameCommand;
            }
        }

        public override void Start()
        {
            _startNewGameCommand = new MvxCommand(() => StartNewGame());
            _continueExistingGameCommand = new MvxCommand(() => ContinueExistingGame());

            base.Start();
        }

        private void ContinueExistingGame()
        {
            throw new NotImplementedException();
        }

        private void StartNewGame()
        {
            ShowViewModel<MainViewModel>();
        }
    }

ShowViewModel is the key here. It navigates to the MainViewModel. MVVMCross uses a convention whereby the view that is shown is based on the VM name; so the view here must be called MainView.

The View

The source view (In this case HomeView) looks like this:

<views:MvxStorePage
    x:Class="MyGame.Views.HomeView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:views="using:Cirrious.MvvmCross.WindowsStore.Views"
    mc:Ignorable="d">

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
            <Button Command="{Binding StartNewGameCommand}" HorizontalAlignment="Center">Start New Game</Button>
            <Button Command="{Binding ContinueExistingGameCommand}" HorizontalAlignment="Center">Continue Existing Game</Button>
        </StackPanel>
    </Grid>
</views:MvxStorePage>

Pretty simple command binding. Now, providing that the destination View and ViewModel exist, and inherit from MvxStorePage, your navigation should now work.

Conclusion

Just the rest of the game to write now…

Windows Tile Updater (Part 6 – Binding a command parameter)

We’re still missing functionality to show the text, or show the text and an image where both are specified.

Add text

Let’s start with the text field. It’s currently just hard coded – that’s pretty straightforward:

        <StackPanel Orientation="Horizontal" Margin="20" Grid.Row="1">
            <TextBlock FontSize="30" Margin="10">Text</TextBlock>
            <TextBox Text="{Binding DisplayText, Mode=TwoWay}" Margin="10"/>
        </StackPanel>

Next, let’s hook this up to the command.

<Button Grid.Row="2" Command="{Binding UpdateCommand}" CommandParameter="{Binding DisplayText}">Update</Button>

So that works, and the logic to show the text tile is quite straightforward:

        public static void UpdateTileText(string text)
        {
            XmlDocument xmlDoc = TileUpdateManager.GetTemplateContent(TileTemplateType.TileWide310x150Text01);

            XmlElement textNode = (XmlElement)xmlDoc.GetElementsByTagName("text")[0];
            textNode.InnerText = text;

            Windows.UI.Notifications.TileUpdater tileUpdater = TileUpdateManager.CreateTileUpdaterForApplication();
            TileNotification tileNotification = new TileNotification(xmlDoc);
            tileUpdater.Update(tileNotification);
        }

So, we can call this, or we can call the UpdateImage. At the moment, we can’t call both. In the next post I’ll look at how we can do this using Multibinding.

Windows Tile Updater (Part 5 – sharing XAML)

In Part 4 we finished with an MVVM app, running on both Windows 8 and Windows Phone. In this post I’m going to explore the idea of using the same XAML.

Is this a good idea?

The very short answer is probably “NO!”. The problem is that in anything but the most trivial of applications, the XAML will need to differ. In this application, it probably doesn’t matter, but then, it wouldn’t kill anyone to maintain two sets of very trivial XAML either.

My approach to this, and to the above question is to create a custom user control, and then use that in both applications. The good thing about this is that it does make sense to share user controls (to me anyway).

New UserControl

We’ll create a View directory in the shared project, and add the UserControl there:

NewView

It should look like this:

<UserControl
    x:Class="TileUpdater.View.MainView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:TileUpdater.View"
    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"
    DataContext="{Binding MVM, Source={StaticResource MainViewModel}}">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal" Margin="20" Grid.Row="0">
            <TextBlock FontSize="30" Margin="10">Image</TextBlock>
            <TextBox Text="{Binding ImagePath}" Margin="10"/>
        </StackPanel>

        <StackPanel Orientation="Horizontal" Margin="20" Grid.Row="1">
            <TextBlock FontSize="30" Margin="10">Text</TextBlock>
            <TextBox Text="My Phone Number: 123456 890 12" Margin="10"/>
        </StackPanel>

        <Button Grid.Row="2" Command="{Binding UpdateCommand}">Update</Button>
    </Grid>
</UserControl>

You’ll be familiar with this XAML by now. Nothing had changed, it’s the same. In the Phone app, we’ll replace the whole XAML with the following:

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

And the Windows 8 XAML with this:

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

    <view:MainView/>
</Page>

Other than the theme, they are the same. You could obviously just have MainPage in the shared project, but personally, I don’t believe that is extensible; if you do so, you run the risk of ending up with an overly complex XAML file trying to cater for each separate project type.

Conclusion

Just a short post this time. In the next post on this, I’m going to add the missing functionality. This should be far easier now that the whole application is basically inside the shared project.

Windows Tile Updater (Part 4 – rationalise the code)

From Part 3 of this tutorial, we finished with a small program running on both Windows 8.1 and Phone 8. It shared most of its business logic, but replicated the XAML. It had an ugly even handler to deal with the single action that it performed. In this post, I’m going to attempt to change this to use the MVVM architecture. I’m also going to do this without using a third party framework.

MVVM

If we are to migrate this to an MVVM pattern, then we will need to do the following:
1. Create a view model
2. Bind the view, to the view model
3. Create a model (the business / tile logic that we have is already a model of sorts).

View Model

I usually find it easier to work from the View Model first.

Note:
I’d normally create this as a separate PCL, but it would appear that shared projects are limited in that they cannot reference any other projects. I found no documentation from MS to say why, or even confirm this was the case. This may well be the subject of a future post.

Anyway, we can create the view model in the shared project:

createmodelinsharedproject

Let’s start with the properties:

namespace TileUpdater.ViewModel
{
    public class MainViewModel : INotifyPropertyChanged
    {
        private static MainViewModel _mvm;
        public static MainViewModel MVM
        {
            get
            {
                if (_mvm == null)
                    _mvm = new MainViewModel();

                return _mvm;
            }
        }

        private string _imagePath = @"c:locationimage.png";
        public string ImagePath
        {
            get { return _imagePath; }
            set
            {
                SetProperty<string>(ref _imagePath, value);
            }
        }

        private string _displayText;
        public string DisplayText
        {
            get { return _displayText; }
            set
            {
                SetProperty<string>(ref _displayText, value);
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null)
        {
            if (Equals(storage, value))
            {
                return false;
            }

            storage = value;
            OnPropertyChanged<T>(propertyName);
            return true;
        }

        private void OnPropertyChanged<T>([CallerMemberName]string caller = null)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(caller));
            }
        }
    }
}

And bind them to the Windows 8 view:

<Page
    x:Class="TileUpdater.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:TileUpdater"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"    
    DataContext="{Binding MVM, Source={StaticResource MainViewModel}}">
       
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal" Margin="20" Grid.Row="0">
            <TextBlock FontSize="30" Margin="10">Image</TextBlock>            
            <TextBox Text="{Binding ImagePath}" Margin="10"/>
        </StackPanel>
        
        <StackPanel Orientation="Horizontal" Margin="20" Grid.Row="1">
            <TextBlock FontSize="30" Margin="10">Text</TextBlock>
            <TextBox Text="My Phone Number: 123456 890 12" Margin="10"/>
        </StackPanel>

        <Button Grid.Row="2" Click="Button_Click">Update</Button>
    </Grid>
</Page>

Quick explanation

I simply created a singleton instance of the view model. Did I have to create a singleton? No – there’s a hundred different ways I could have done this; if I had several view models then you could create a small dictionary with them in (in the style of MVVMLight). I specifically didn’t want to use a framework here, and I didn’t want to overcomplicate – say what you like about singletons, but they are simple.

Now let’s bind the phone

Take the XAML in the Windows 8 XAML and paste it into MainPage.xaml:

…
DataContext="{Binding MVM, Source={StaticResource MainViewModel}}">
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal" Margin="20" Grid.Row="0">
            <TextBlock FontSize="30" Margin="10">Image</TextBlock>            
            <TextBox Text="{Binding ImagePath}" Margin="10"/>
        </StackPanel>
        
        <StackPanel Orientation="Horizontal" Margin="20" Grid.Row="1">
            <TextBlock FontSize="30" Margin="10">Text</TextBlock>
            <TextBox Text="My Phone Number: 123456 890 12" Margin="10"/>
        </StackPanel>

        <Button Grid.Row="2" Click="Button_Click">Update</Button>
    </Grid>

Command Binding

The next step is to bind the commands. MVVM Light allows RelayCommand for this purpose, but let’s see what we can do on our own.

The first step is to bind the command. For now, let’s just do this in the Windows 8 MainPage.xaml:

        <!--<Button Grid.Row="2" Click="Button_Click">Update</Button>-->
        <Button Grid.Row="2" Command="{Binding UpdateCommand}">Update</Button>

We’ve now bound the command, but have nothing to bind. Without a framework, this is very much a matter of rolling your own. First, you need to add the command:

addupdatecommand

The implementation is quite simple:

namespace TileUpdater.ViewModel
{
    class UpdateCommand : ICommand
    {
        public bool CanExecute(object parameter)
        {
            return true;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            TileUpdater.UpdateTile.UpdateTileImage();
        }
    }
}

Finally, just link this up the the ViewModel (TileUpdater.Shared):

        private ICommand _updateCommand;
        public ICommand UpdateCommand
        {
            get
            {
                if (_updateCommand == null)
                {
                    _updateCommand = new UpdateCommand();
                }
                return _updateCommand;
            }
            set { _updateCommand = value; }
        }

Needless to say that we need to make the same change in the phone app. The XAML for MainPage should be exactly the same:

        <!--<Button Grid.Row="2" Click="Button_Click">Update</Button>-->
        <Button Grid.Row="2" Command="{Binding UpdateCommand}">Update</Button>
    </Grid>

What about the Model – isn’t this just VVM?

Okay – so, we’re now basically using the MVVM pattern. We don’t technically have a Model, though. Actually, TileUpdater is really the Model, so let’s simply call it one:

justcallitamodel

Conclusion

Now we’re running an MVVM pattern and sharing most of the code. However, there’s a lot of duplicate XAML, and the UI is a bit scrappy, so We’ll have a look at that in the next post.

Unit Testing an MVVM RelayCommand

The RelayCommand is an excellent way to communicate between a view and View Model in MVVM without creating a link to a specific instance of either. However; one problem that I recently encountered when using these was: how are they unit tested.

Take the following piece of code (taken from https://tfsutilities.codeplex.com/):

    public class MainViewModel : ViewModelBase
    {          
        public RelayCommand FindOrphanedWorkspaceCommand { get ; private set ; }

This is instantiated here:

         public MainViewModel( IDataService dataService)
        {
            ...

            FindOrphanedWorkspaceCommand = new RelayCommand(FindOrphanedWorkspaces);

And, finally, the method itself:

         /// <summary>
        /// Call method to retrieve all workspaces that currently have no pending changes
        /// </summary>
        private void FindOrphanedWorkspaces()
        {
            // Doesn't really matter what this actually does

So; can we just write a test; what about this:

    [TestClass]
    public class MainViewModelTest
    {
        [ TestMethod]
        public void FindOrphanedWorkspaces()
        {
            IDataService ds = new Mock.MockDataService ();
            MockMainViewModel mvm = new MockMainViewModel (ds);

            mvm.FindOrphanedWorkspaceCommand();

        }

The answer, of course, is no (otherwise this wouldn’t be a particularly useful blog post).

The Workaround

There is a workaround (which is pretty much by fallback workaround these days when I find something can’t be unit tested for reasons of protection):

Simply change the private method to protected and subclass the viewmodel:

    class MockMainViewModel : MainViewModel
    {
        public MockMainViewModel( IDataService dataService) : base (dataService) { }

         public void FindOrphanedWorkspaces()
        {
            base.FindOrphanedWorkspaces();

This certainly works and, in its defence, it tests as completely as calling the RelayCommand (I don’t believe testing the MVVM architecture is within the remit of the test architecture of any dependent program).

However…

It feels like a lot of additional work (as it happens, it’s work you may have to do anyway for other things, but that’s beside the point). So, what’s the alternative?

RelayCommand implements ICommand, here’s the metadata:

namespace GalaSoft.MvvmLight.Command
{
    // Summary:
    //     A command whose sole purpose is to relay its functionality to other objects
    //     by invoking delegates. The default return value for the CanExecute method
    //     is 'true'. This class does not allow you to accept command parameters in
    //     the Execute and CanExecute callback methods.
    public class RelayCommand : ICommand
    {
        // Summary:
        //     Initializes a new instance of the RelayCommand class that can always execute.
        //
        // Parameters:
        //   execute:
        //     The execution logic.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     If the execute argument is null.
        public RelayCommand( Action execute);
        //
        // Summary:
        //     Initializes a new instance of the RelayCommand class.
        //
        // Parameters:
        //   execute:
        //     The execution logic.
        //
        //   canExecute:
        //     The execution status logic.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     If the execute argument is null.
        public RelayCommand( Action execute, Func< bool> canExecute);

        // Summary:
        //     Occurs when changes occur that affect whether the command should execute.
        public event EventHandler CanExecuteChanged;

        // Summary:
        //     Defines the method that determines whether the command can execute in its
        //     current state.
        //
        // Parameters:
        //   parameter:
        //     This parameter will always be ignored.
        //
        // Returns:
        //     true if this command can be executed; otherwise, false.
        public bool CanExecute( object parameter);
        //
        // Summary:
        //     Defines the method to be called when the command is invoked.
        //
        // Parameters:
        //   parameter:
        //     This parameter will always be ignored.
        public virtual void Execute( object parameter);
        //
        // Summary:
        //     Raises the GalaSoft.MvvmLight.Command.RelayCommand.CanExecuteChanged event.
        public void RaiseCanExecuteChanged();
    }
}

Consequently, you can simply do this:

        [ TestMethod]
        public void FindOrphanedWorkspaces()
        {
            IDataService ds = new Mock.MockDataService ();
            MockMainViewModel mvm = new MockMainViewModel (ds);

            mvm.FindOrphanedWorkspaceCommand.Execute( null);

        }

And, there’s more. If you’ve implemented the CanExecute, you can test if that works; for example:

Assert.IsTrue(mvm.FindOrphanedWorkspaceCommand.CanExecute(null));

Or

Assert.IsFalse(mvm.FindOrphanedWorkspaceCommand.CanExecute(null));

In my case, as it stands, the former.

Conclusion

So, we can check whether the command can execute, and whether it does execute. Admittedly this isn’t ground-breaking research, but it took me longer that it should have to figure it out, and next time, I’ll have a blog post to refer to.

Implementing single cell copy and full row Item Selection in WPF DataGrid

Recently, I came across a strange problem with a DataGrid while using the MVVM-Light pattern. The problem was that I needed to implement two, seemingly similar pieces of functionality:

1. To copy any given cell in the data grid
2. To search the database, based on a specific piece of data in the selected row of the datagrid (regardless of which cell was selected).

To implement the Copy feature was unbelievably easy – you don’t even need a custom command; just add the following setting to the DataGrid:

SelectionUnit ="CellOrRowHeader"

And the following context menu:

<DataGrid.ContextMenu>
    <ContextMenu>                    
       <MenuItem Command="Copy"/>                    
    </ContextMenu>
</DataGrid.ContextMenu>

And the copy is done!

So, next, I wanted to implement the custom search. I needed to identify the currently selected row in my ViewModel, so I added a new property:

        private MyDataClass _selectedItem;
        public MyDataClass SelectedItem
        {
            get { return _selectedItem; }
            set
            {
                _selectedItem = value;
                RaisePropertyChanged(() => SelectedItem);
            }
        }

I then bound this to the selected item of the datagrid, like this:

     < DataGrid ItemsSource ="{ Binding Path =MyDataCollection}"                   
                  SelectedItem="{ Binding Path =SelectedItem}"                   
                  SelectionUnit ="CellOrRowHeader"  
&#91;/sourcecode&#93;

And finally, created my command:

&#91;sourcecode language="csharp"&#93;
         public RelayCommand MyCommand { get ; private set ; }
&#91;/sourcecode&#93;

In the constructor, initialised it:

&#91;sourcecode language="csharp"&#93;
     this.MyCommand = new RelayCommand (() => this.MyCommandFunc());

Created the function:

         private void MyCommandFunc()
        {
            QueryDB(SelectedItem.ValueOne);
        }         

And, finally, setup the context menu:

<DataGrid.ContextMenu>
    <ContextMenu>                    
         <MenuItem Command ="Copy"/>                    
         <MenuItem Header ="My Funky Command" Command="{Binding MyCommand}"/>
    </ContextMenu>
</DataGrid.ContextMenu>

But this didn’t work! (Queue dramatic music).

The problem is down to this:

SelectionUnit ="CellOrRowHeader"

So, change it to:

SelectionUnit="FullRow" 

And it works again… but now copy doesn’t work, because it copies the FULL ROW!

So, the two features are incompatible?

I did find a workaround which doesn’t breach the separation of concerns. Please note that, although this does work, and does not breach separation of concerns, it may or may not be the best way of doing it. If you have, or know of, a better way the PLEASE leave a comment, or mail me and let me know.

The Workaround

Instead of binding the SelectedItem property, bind the Tag property of the grid:

< DataGrid ItemsSource ="{ Binding Path =MyDataCollection}" Tag="{ Binding Path =SelectedItem}" SelectionUnit ="CellOrRowHeader" [/sourcecode] Now, we need a little code-behind, which must remain agnostic to the ViewModel: [sourcecode language="csharp"] private void DataGrid_SelectedCellsChanged( object sender, SelectedCellsChangedEventArgs e) { (( DataGrid)sender).Tag = ((DataGrid)sender).SelectedCells.FirstOrDefault().Item; } [/sourcecode] Now, because the SelectedItem is bound in the view to the Tag, updating the Tag, updates the SelectedItem. This means that when you call your function (as described above): [sourcecode language="csharp"] private void MyCommandFunc() { QueryDB(SelectedItem.ValueOne); } [/sourcecode] SelectedItem is now set. Conclusion

Whilst I can see why this works the way it does, it doesn’t seem sensible that I need to jump through so many hoops to get this to work without breaking the separation of concern. It may just be a quirk with the DataGrid, but it feels like a hack – which I don’t like. Nevertheless, ATM it’s the only solution that I can come up with that doesn’t mean directly referencing the View from the ViewModel.

Implementing a call to search using MVVM Light

I recently started using the MVVM Light framework to create an app. One of the first things that I found tripped me up was trying to link the ViewModel functionality with the visual interface. After a little more searching than should be necessary I came across the concept of commands. Basically, thos allows you to bind the functionality of your view model to an action on the screen. In the example below it’s the action of clicking a button.

First, create a new relay command (this is in the namespace GalaSoft.MvvmLight.Command):

    public class MainViewModel : ViewModelBase
    {
        private readonly IDataService _dataService;

        /// <summary>
        /// The <see cref="WelcomeTitle" /> property's name.
        /// </summary>
        public const string WelcomeTitlePropertyName = "WelcomeTitle" ;

        private string _welcomeTitle = string.Empty;

               // New Command Variable
        public RelayCommand SearchCommand { get ; private set ; }
        ...

Next initialise the command in the constructor of the VM:

        public MainViewModel( IDataService dataService)
        {
            this.SearchCommand = new RelayCommand (this.GetDataCount);
            ...

Obviously, the execute function must exist. For example:

        private void GetData()
        {
                _dataservice.GetData((count, error) =>
                {
                    if (error != null)
                    {
                        // Report error here
                        return;
                    }

                    // Do something with data here
                });
        }

Finally, simply add a call from the XAML in MainWindow:

Parameters

You can also pass parameters, by simply providing the CommandParameter attribute and then using it. However, given that you’re already in the databound context (i.e. you’re function is in your ViewModel, which is bound to the DataContext) I didn’t find a need for this, as it’s possible to simply reference the property directly.

Conclusion

This ends up being quite a neat way to link the two. The screen is linked to the view model without having a chunk of code in the button click handler.