Tag Archives: Windows 8

MVVM Cross Upgrade to 4.2.2

Coming back to MVVMCross and trying to create a new project, I found that some of the documentation available for the new version (4.2.2 at the time of writing this) is no longer correct; for example, the ToDo file in the sample projects still looks like this:

The steps to get this Store UI working are:

1. Add a reference to your Core PCL project
2. Change App.Xaml.cs so that it creates a ‘new Setup(RootFrame)’ during its OnLaunched:

protected override void OnLaunched(LaunchActivatedEventArgs args)
{
var rootFrame = Window.Current.Content as Frame;

// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();

if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}

// Place the frame in the current Window
Window.Current.Content = rootFrame;
}

if (rootFrame.Content == null)
{
// When the navigation stack isn’t restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter

var setup = new Setup(rootFrame);
setup.Initialize();

var start = MvvmCross.Core.Mvx.Resolve();
start.Start();
}
// Ensure the current window is active
Window.Current.Activate();
}

3. For Windows 8 – Add a views folder and a view – xaml.cs and .xaml based on BasicPage – this
will add 5 files to the Common folder.
– Change the Common/LayoutAwarePage.cs inheritance to MvvmCross.WindowsStore.Views.MvxStorePage
– Change the Common/LayoutAwarePage.cs – remove the OnNavigatedTo and OnNavigatedFrom handlers
– Add some content for your Xaml – e.g.

5. For Windows 8.1 – Add a views folder and a view based on the BasicPage template
– In the .xaml.cs – remove public NavigationHelper NavigationHelper and all referencing code
– In the .xaml.cs – remove the OnNavigatedTo and OnNavigatedFrom handlers
– Add some content for your Xaml – e.g.

This document was very useful. I was looking specifically at the Babel project in the above sample; this won’t compile under MvvmCross 4.2.2. I’ve listed here everything I needed to do to make it.

Mvx has now been replaced with MvxSimpleIoCContainer.Instance

In App.xaml.cs:

var start = MvxSimpleIoCContainer.Instance.Resolve<IMvxAppStart>();

Is now:

var start = MvxSimpleIoCContainer.Instance.Resolve<IMvxAppStart>();
start.Start();

In App.cs:

        private void InitializeText()
        {
            var builder = new TextProviderBuilder();
            Mvx.RegisterSingleton<IMvxTextProviderBuilder>(builder);
            Mvx.RegisterSingleton<IMvxTextProvider>(builder.TextProvider);
        }

Is now is a separate plug-in by the looks of things:

mvvmcrossupgrade

The new code is:

        private void InitializeText()
        {            
            var builder = new TextProviderBuilder();
            MvxSimpleIoCContainer.Instance.RegisterSingleton<IMvxTextProviderBuilder>(builder);
            MvxSimpleIoCContainer.Instance.RegisterSingleton<IMvxTextProvider>(builder.TextProvider);
        }

How to Draw a Diagonal Line Using Only XAML (and no path data)

I’ve been playing around with an app to maintain a score. The first thing that I wanted to do was to split the screen, but I wanted a diagonal split; similar to this:

phonescreen

There are a number of ways that this can be achieved; however, this is a method using only XAML. The same method will (I believe) work on Windows 8, WPF and Windows Phone.

First, split the screen into three rows or columns (which depends on how you want the orientation):

        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

This needs to be an odd number of rows / columns if you want the line to be central; additionally, an increased number of rows or columns will result in a smaller incline. Next, draw a transparent rectangle across the middle grid square:

        <Rectangle Name="Placeholder" Grid.Row="1" 
                   HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                   Opacity="0"/>

Finally, simply draw a line, binding the X2, Y2 values to the height and width of your rectangle:

        <Line Grid.Row="1" 
              X1="0" X2="{Binding ActualWidth, ElementName=Placeholder}"
              Y1="0" Y2="{Binding ActualHeight, ElementName=Placeholder}"
              StrokeThickness="2" Stroke="Blue"/>

Conclusion

I’m not saying the is the best, most efficient, or only way of doing this. However, it does mean that I can do it on both Windows Phone and Windows Store (and in WPF if I were so inclined) using a single shared project.

Reading NumPad keys using WinRT

Recently, I discovered a bug with one of my Windows Store games – Maths Races. The issue was that when a number key was pressed, the program works fine, but pressing a number pad key – even with NumLock on wasn’t recognised.

Here’s the code that I was using the detect the keypress:

KeyboardState newState = Keyboard.GetState();
var keys = newState.GetPressedKeys();

foreach (var key in keys)
{
    if (!IsNewKeyPressed(key))
        continue;

    byte keychar;
    if (byte.TryParse(key.GetHashCode().ToString(), out keychar))
    {
        char newChar = Convert.ToChar(keychar);

        if (Char.IsNumber(newChar))
        {
            . . . 

So, when I press a number pad key with Num Lock off, it behaves as though I’d pressed a different character; for example NumPad0 resolves to a key character code of 96:

(byte.TryParse(key.GetHashCode().ToString(), out keychar))

Which when converted to a char is “`”.

Okay, so here’s how I got around this:

if (key.HasFlag(Keys.NumPad0 & Keys.NumPad1 & Keys.NumPad2 &
    Keys.NumPad3 & Keys.NumPad4 & Keys.NumPad5 & Keys.NumPad6 &
    Keys.NumPad7 & Keys.NumPad8 & Keys.NumPad9))
{
    char number = key.ToString().Substring(6)[0];
    . . .
}                
else
   . . .

Admittedly it isn’t very pretty, and if someone knows a better, or more elegant way to do this, then please let me know.

Windows 10 – The Return of the Overrated Start Menu

Yesterday, for the first time, I saw Windows 10. I set it up in a VM inside Win 8. The following post in a combination of conjecture, opinions, and under researched hearsay.

First, let’s think about what I just said: I’m running a later version of Windows inside an earlier one. And it works.

9

Don’t mention 9! I mentioned it once, but I think I got away with it.

Start menu

The start menu never went anywhere for Win 8. You just press the Windows key and you’re in it (although it was more of a screen than a menu). Anyway, MS finally bowed to pressure, and it’s back:

start1

Looks good eh? Actually, after restarting it seemed to gather its thoughts:

start2

Anyway, as I understand the intention, if I were running this on a tablet, I’d be able to see the Win 8 start screen when I pressed the Windows Key. I can’t test that on a VM and, if I could, I’d be surprised if it worked properly for the TP.

Multiple Desktops

This is a neat feature: the ability to maintain more than one desktop. The way this appears to work is that you can open apps into any desktop, and then just switch between desktop to access them, or access them from the taskbar, and Windows will select the desktop they are on.

desktop

You appear to be able to maintain as many desktops as you like.

Search

There is a large magnifying glass on the taskbar, which brings up a huge, unwieldy, blank box with a small text search. Maybe this will be back on the charms bar for tablets, but the idea is that it will find stuff on your machine. It failed:

search

I don’t understand why this was separated from the start menu. Searching for, and running programs are basically the same thing. If I want to run word, I want to type “Word”; if I want to open a word document on my desktop, I want to type: “My word doc” and have it find it. Results seemed to be sporadic, sometimes it found what I expected, but generally it didn’t.

What happened to the charms bar?

It now seems to be a sub menu of each store window:

charmsbar

As I said earlier, I expect it will behave differently for the tablet and phone.

Universal Apps

These have been around for a while. They basically allow sharing of code between Windows store and Windows phone apps. As I understand it, these will now be effectively mandatory – you will have to produce a phone & store version, in the same way as you had to provide a snapped and filled version of your app.

Conclusion

The split desktop is nice, and the idea of having “One Windows” is a nice one. In fact, it’s effectively what I understood to be the driving force behind 8. It looks like it’s going to be a good OS, but I can’t see any killer features.

What I mean by that is this: imagine that you want to upgrade to Windows 10, and you put the idea to your boss. The first question they should ask is: “Why?”.

For Windows 8, the answer was simple: Hyper-V. An astoundingly useful and undersold feature.

Windows 10 doesn’t have that, and it needs it, because a lot of people are sticking on 7 and need a reason to upgrade – having the start menu back is not that reason.

MVVMCross – ShowViewModel not working?

I thought I’d jot this down, as it had me for a short while. Imagine that you have a line of code that looks like this:

ShowViewModel<MyViewModel>();

But nothing happens when you call it.

The Output Window

The output window is definitely your friend with MVVMCross; it may say something like this:

mvx:Diagnostic: 36.44 Error seen during navigation request to MyViewModel – error KeyNotFoundException: Could not find view for MyApp.PCL.ViewModels.MyViewModel
at Cirrious.MvvmCross.Views.MvxViewsContainer.GetViewType(Type viewModelType)
at Cirrious.MvvmCross.WindowsStore.Views.MvxStoreViewPresenter.Show(MvxViewModelRequest request)

So, what’s the problem?

Some things to check: firstly, check that you are using an MVVMCross view; that is, for example, in Windows 8, you need your page to inherit from MvxStorePage, not Page:

Conclusion

Nothing here that you won’t see on one of Stuart Lodge’s tutorials, and probably a good handful of SO questions. So now it’s here as well.

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.

Windows Tile Updater (Part 7 – Multibinding command parameters)

We left the last post where the Tile Updater could update text, or images, but we basically had to choose which at design time. In this post, I’m going to pass through the image and text, and have the command work out which to update.

Note: you can have both image and text in live tiles. Look out for that in a future post.

Multibinding

The first thing to know about multibinding for WinRT is that it doesn’t exist. However, to get around this, we can simply take the same approach that we do with a function – a function can only return one value, but that value can be a class; so we’ll bind to the VM (one of the advantages of exposing a static singleton instance of the VM):

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

The command itself needs to look something like this for now:

        public bool CanExecute(object parameter)
        {
            MainViewModel mvmInst = (MainViewModel)parameter;
            if (mvmInst == null) return false;

            if (string.IsNullOrWhiteSpace(mvmInst.ImagePath) &amp;&amp; string.IsNullOrWhiteSpace(mvmInst.DisplayText))
                return false;
            return true;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            MainViewModel mvmInst = (MainViewModel)parameter;

            if (string.IsNullOrWhiteSpace(mvmInst.ImagePath))
                TileUpdater.Model.UpdateTile.UpdateTileText(mvmInst.DisplayText);
            else
                TileUpdater.Model.UpdateTile.UpdateTileImage(mvmInst.ImagePath);
        }

There’s a couple of points here:
1. The CanExecute will not prevent the command from firing where neither parameter has a value.
2. It doesn’t disable the button when this occurs.

And that’s it – we now have a command that can accept multiple parameters and update either image or text depending on what is displayed.

Conclusion

Okay, strictly speaking, this is not multi-binding. It does however, solve the problem. I suppose the design question would be: does it introduce a tighter coupling than multi-binding?

It definitely does; however, with a bit of manipulation, you could introduce a mini-VM that just had the parameters that you need. However, for most cases, I would think that it was fine to just pass the VM to the command. We’ll see if this comes back to bite me when we start putting some unit tests in place.

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

Windows Tile Updater (Part 3 – Move the code to a shared project and create the Phone App)

In the third part of my series on creating a universal app, I’m going to transfer the code that we created in part 2 and move it into a shared project.

If you want to have a look at the source code, or just use it for something, it’s here:

https://windowstileupdater.codeplex.com/

So far, we have code to update the tile, but it’s in the Windows 8.1 app. Let’s just move that to the shared project:

movetoshared

TileUpdater.cs looks like this:

    public class UpdateTile
    {
        private static void UpdateTileImage(string image)
        {
            XmlDocument xmlDoc = TileUpdateManager.GetTemplateContent(TileTemplateType.TileWide310x150Image);

            XmlElement imageNode = (XmlElement)xmlDoc.GetElementsByTagName("image")[0];
            imageNode.SetAttribute("src", string.Format("ms-appx://{0}", image));

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

        public static void UpdateTileImage()
        {
            string image = "/Assets/test.png";
            UpdateTileImage(image);
        }
    }

You might notice this is precisely the same code. The button click event on the main page looks like this now:

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            TileUpdater.UpdateTile.UpdateTileImage();            
        }

Now, run again and the behaviour should remain the same. This isn’t much – I mean, if you’re reading this and have just found out how to separate code from the main program then you might be reading the wrong blog. So, let’s try wiring up the phone app. We’ll start with the XAML:

    <Grid>
        <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="c:locationimage.png" 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>

The XAML is familiar – I copied it verbatim from the Win 8 app (as I said in the last post, I will try to rationalise this a little, although other than in a very trivial app such as this, you would probably want the XAML to be different). And the code behind:

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            TileUpdater.UpdateTile.UpdateTileImage();
        }

And, it works:

phoneappstartscreen

Did it just work – just like that?

Well, no.

Okay – there was some fiddling – here’s the fiddling:
1. The app will (again) not be pinned to the start screen, you’ll need to use the emulator to do so.
2. The tile will, again, initially be a small square (half the size of a wide tile – 150 x 150); this will need to be a wide tile, and to do so, you need to press and hold and the first reduce the size, before increasing to a wide tile.

Conclusion

Okay – so, we now have a Windows Store and Phone App. There’s a common codebase (admittedly it’s a bit scrappy), and the phone app took around 20 seconds.

In the next post I’m going to tidy up the code and investigate options for using shared XAML.