Nick's .NET Travels

Continually looking for the yellow brick road so I can catch me a wizard....

The Danger of Setting CacheMode to BitmapCache on Windows 8

This week has been full of interesting challenges as we worked to release another Windows 8 application for a client. Credit must go to the client who has set the expectation bar at an incredibly high level – I truly wish all clients had this level of respect for their brand, identity, apps, website etc. One of the challenges we came up against was with a very persistent image that refused to display correctly. By correctly I mean without any distortion, blurring, pixelation etc that happens when you incorrectly resize images. Now we only really saw this on the Surface 2 which runs at a scale factor of 140 and it was clearly evident that the image that was displayed was blurry. Following all the documentation and guidance we provided images at 100, 140 and 180 scale factors and validated that the correct image was being show by tagging each image to make them slightly unique. We also ensured that the image element was the correct size for the image and that Stretch was set to None (interesting side note – it appears that even if the element size matches the image size, if you leave Stretch to its default value of Uniform you end up with some visual distortion).

Even after doing all of that we still ended up with an image that was slightly blurry – enough that you’d have thought the image had been blown up slightly. It turns out that we had set CacheMode=BitmapCache on a parent element to ensure that when we animated the elements they would animate together. Removing the CacheMode attribute resulted in the image appearing crystal clear.

Ok, so here’s the original.

image

 

Here’s an image where the left side is taken from an element with CacheMode=BitmapCache, the right side is from an element without this attribute – spot the difference (hint, look at the edge of the spiral towards the centre)

image

 

Here’s an image where the top is taken from an element with CacheMode=BitmapCache, the bottom side is from an element without this attribute – again you should be able to see the difference.

image

 

Call out to mobile developers out there – do you care this much about your apps? If not, then you need to re-evaluate your quality bar.

Remove Tap/Mouse Down Animations on GridView and ListView for Windows 8.1

<disclaimer> The reason that the GridView and ListView have built-in animations for when a user taps or mouse-downs on an item is to provide feedback that they have indeed tapped/mouse downed on an item. I highly discourage the removal of these built-in animations as it will detract from your user experience. That said, there are times where you may need to remove these animations. For example if you nest a ListView within an item of a GridView, then, depending on what you want tappable, you’ll need to remove the animations on either the GridView or ListView.</disclaimer>

*If you’re building for Windows 8.0 then I suggest taking a look at some of the existing posts out there on how to remove storyboards from the ItemContainerStyle (eg http://stackoverflow.com/questions/10359197/windows-8-gridview-disabling-item-tap-visualization)

A lot of the discussion on the web is on how to remove various transitions from elements in Windows 8/8.1. For example setting the Transitions property to an empty TransitionsCollection. However, after setting virtually every transitions property I could find, I was still seeing the tap animation. It turns out that one solution is much simpler than I’d thought, and can be useful if you want to get rid on all the built in GridView/ListView item effects. Be warned, this will remove all those built-in effects!

Let’s walk through a simple example:

- Create a new Windows application based on the Hub App template – this will give us a GridView to work with. You can also use the Grid App if you want.

- Open the application in Blend (right-click the project and select “Open in Blend”)

- Locate a GridView to modify – we’re going to use the GridView in Section 3 of the Hub

- Right-click the GridView and select Edit Additional Templates –> Edit Generated Item Container (ItemContainerStyle) –> Edit a Copy

image

- Switch to code mode (I prefer split mode) and delete (or comment out) the GridViewItemPresenter element.

- Add an empty ContentPresenter element.

<Style x:Key="GridViewItemStyle1" TargetType="GridViewItem">
    <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
    <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="TabNavigation" Value="Local"/>
    <Setter Property="IsHoldingEnabled" Value="True"/>
    <Setter Property="Margin" Value="0,0,2,2"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="GridViewItem">
                <ContentPresenter />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

- Run the application – you’ll notice that there is no tap animation on the GridView in section 3, yet it still responds to tap or mouse click on the item (just no visible feedback).

Note: If you have a GridView or ListView that isn’t interactive you can always either disable it or set the IsHitTestVisible property to false.

Taking Visual States Cross Platform to iOS and Android with Xamarin

Last Friday at the Windows Phone 8.1 developer training, run by Microsoft, Nokia Microsoft and Built to Roam, we asked the room how many people used Blend and knew about Visual States. I was shattered to see very few people even knew what a Visual State was, let alone use them in their code. Visual States have to be one of the most useful aspects of the XAML system allowing you to define different states for not only your pages but also controls and user controls that you create.

On Tuesday night before the Sydney Mobile .NET Developer Meetup I was talking with Lewis Benge about how developers on other platforms control aspects of their user interface. The consensus is that it’s very reactive in that as elements of their data model, or in the case of mvvmcross elements of the view model, change elements of the UI are adjusted. For example if you were displaying some form of a loading indicator whilst some data was being retrieved from a service, when the call was complete, the progress indicator would be hidden. In this simple case you might think that it’s just one line of code to show or hide the progress indicator but now repeat this two or three times and all of a sudden you have UI control code littered throughout your application logic. In the XAML world we’d simply define these as visual states and we’d move between those states as required. In fact, as you’ll see we can even represent these states within our view model so that the state, not the visual representation of the states, form part of our application logic (and can be isolated and tested independently as it can sit nicely within a PCL).

Ok, now for a more concrete example:

- File –> New Project –> Windows Phone application

- Add New Project –> Android application

(you can repeat for iOS if you want)

- Add New Project – Portable Class Library

- Manage NuGet –> Add Mvvmcross to all projects, and follow “ToDos” as required for each project

>> At this point, you want to make sure that both your Windows Phone and Android applications build and can be run. They should both launch FirstView and contain a textbox and label with databinding working so that you can change the text in the textbox and it is updated in the label.

Blending some Visual States

We’re going to add a progress bar and a piece of text to say “Loading….” whilst data is being loaded.

- Right-click the Windows Phone project and select Open in Blend

- Add a progress bar and texblock to the contentpanel element to give you the following xaml – note that both elements are currently collapsed

<Grid x:Name="ContentPanel"
        Grid.Row="1"
        Margin="12,0,12,0">
    <ProgressBar x:Name="progressBar"
                    Visibility="Collapsed" />
    <TextBlock x:Name="textBlock"
                TextWrapping="Wrap"
                Text="Loading..."
                VerticalAlignment="Center"
                HorizontalAlignment="Center"
                Margin="0,-25,0,0"
                Visibility="Collapsed" />
</Grid>

- In the States tool windows, click the “Add state group” button in the icon bar. Call the state group “LoadingStates” (this name is somewhat irrelevant as it’s never used other than in Blend to allow you to differentiate if you have multiple state groups)

- Click the “Add state” button twice to generate states “Loading” and “Loaded”

- With the Loading state selected (there should be a red border around the main design surface indicating that you’re in state editing mode) set both textblock and progressbar to visible, and set the isindeterminate property to true. If you look at the xaml you should see the following states defined:

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="LoadingStates">
        <VisualState x:Name="Loading">
            <Storyboard>
                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                                Storyboard.TargetName="progressBar">
                    <DiscreteObjectKeyFrame KeyTime="0">
                        <DiscreteObjectKeyFrame.Value>
                            <Visibility>Visible</Visibility>
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                </ObjectAnimationUsingKeyFrames>
                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(ProgressBar.IsIndeterminate)"
                                                Storyboard.TargetName="progressBar">
                    <DiscreteObjectKeyFrame KeyTime="0">
                        <DiscreteObjectKeyFrame.Value>
                            <System:Boolean>True</System:Boolean>
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                </ObjectAnimationUsingKeyFrames>
                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                                Storyboard.TargetName="textBlock">
                    <DiscreteObjectKeyFrame KeyTime="0">
                        <DiscreteObjectKeyFrame.Value>
                            <Visibility>Visible</Visibility>
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                </ObjectAnimationUsingKeyFrames>
            </Storyboard>
        </VisualState>
        <VisualState x:Name="Loaded" />
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

- If you switch between the Loading and Loaded states in Blend you should see the elements show and hide as expected. Now we need to wire up some logic to switch between these states at runtime.

- Return to Visual Studio and go to the code-behind file for the FirstView (Windows Phone project).

- Add the following code to the OnNavigatedTo method:

protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    VisualStateManager.GoToState(this, "Loading", true);
    await Task.Delay(2000);
    VisualStateManager.GoToState(this, "Loaded", true);
}

- Run the Windows Phone application and observe the application switching between the two states

- Now we need to move this logic one step further away from the UI layer and have it contained within our ViewModel. We’ll also try to eliminate those pesky string literals. To do this we’ll define an enumeration in code so that we can refer to our VisualStates – the name of the enumeration doesn’t matter but the name of the enumeration values needs to match the names of the states defined in Blend

public enum FirstStates
{
    Base,
    Loading,
    Loaded
}

- To move our state logic into the ViewModel we’ll need a way to trigger the actual state change in the UI layer (ie the view). For this we’ll expose an event on the ViewModel which will include the name of the state that we want the view to transition to. We’ll start by defining a StateEventsArgs class which we’ll use to wrap the name of the state. This class includes a couple of helper methods to make it easy to generate an instance from an enumeration value, and to return an enumeration value. You might ask why we’re converting to and from strings – we’ll come back to this!

public class StateEventArgs : EventArgs
{
    public string StateName { get; private set; }

    public static StateEventArgs Create<TState>(TState state) where TState : struct
    {
        return new StateEventArgs {StateName = state.ToString()};
    }

    public TState AsState<TState>() where TState : struct
    {
        TState state = default(TState);
        Enum.TryParse(StateName, true, out state);
        return state;
    }
}

- Update the FirstViewModel to raise a StateChanged event as follows:

public void OnStateChanged(FirstStates state)
{
    if (StateChanged != null)
    {
        StateChanged(this, StateEventArgs.Create(state));
    }
}
public override async void Start()
{
    base.Start();
    await Task.Yield(); // Attach state changed event handler

    OnStateChanged(FirstStates.Loading);
    await Task.Delay(5000);
    OnStateChanged(FirstStates.Loaded);
}
public event EventHandler<StateEventArgs> StateChanged;

- Now, in the code behind for our FirstView we can amend the OnNavigatedTo method to wire up a StateChanged event handler:

protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    (ViewModel as FirstViewModel).StateChanged += FirstView_StateChanged;
}

void FirstView_StateChanged(object sender, StateEventArgs e)
{
    VisualStateManager.GoToState(this, e.StateName, true);
}

- When you run this, there is a 5 second delay during the Start method in the FirstViewModel during which the Loading state should be visible. There after it should revert to the Loaded state.

- Let’s flip across to our Android project and amend the FirstView to include the following xml.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="40dp"
        local:MvxBind="Text Hello" />
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="40dp"
        local:MvxBind="Text Hello" />
    <Button
        android:id="@+id/MyButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/Hello" />
    <ProgressBar
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/progressBar1" />
</LinearLayout>

- Note that unlike in XAML for Windows Phone we can’t define the visual states in xml. Instead we define them as a set of Actions which will be invoked when transitioning to a particular state. In this case we’re setting the progress bar to indeterminate and changing the button color for Loading state. You’ll notice that unlike in XAML where we could rely on the state manager to revert state changes (ie Loaded state simply reverses any changes applied by the Loading state), here we have to be explicit about all changes we want to occur.

private IDictionary<FirstStates, Action> states;
protected override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);
    SetContentView(Resource.Layout.FirstView);

    var button = FindViewById<Button>(Resource.Id.MyButton);
    button.Click += (s,e) => ViewModel.Start();

    var progress = FindViewById<ProgressBar>(Resource.Id.progressBar1);

    states = new Dictionary<FirstStates, Action>()
    {
        {FirstStates.Loading, () =>
        {
            progress.Indeterminate = true;
            button.SetTextColor(new Color(0,255,0));
        }},
        {FirstStates.Loaded, () =>
        {
            progress.Indeterminate = false;
            button.SetTextColor(new Color(255,0,0));
        }}
    };
}

- The final piece is to wire up an event handler to the StateChanged event, the same as we did for Windows Phone:

protected override void OnViewModelSet()
{
    base.OnViewModelSet();

    (ViewModel as FirstViewModel).StateChanged += FirstView_StateChanged;
}

void FirstView_StateChanged(object sender, StateEventArgs e)
{
    var state = e.AsState<FirstStates>();
    var change = states[state];
    change();
}

- When the StateChanged event is trigger, we find the appropriate Action by looking in the state Dictionary. The Action is then invoked to apply the appropriate visual changes.

In this post I’ve walked you through the basics of how you can use visual states across both Android and Windows Phone, controlled from within your view models. This same model can be applied to iOS and of course the code for wiring up the state changed event can be abstracted into base view models and base views so you don’t need to add it to every page.

Using Universal Share Projects for Windows Phone Silverlight 8.0 and 8.1 Upgrade Path

Of course with the announcement of Windows Phone 8.1 XAML applications (ie applications for WP8.1 written in Windows XAML) and support for Universal applications, not everyone is going to immediately rebuild their Windows Phone application. Instead, existing developers need a mechanism to upgrade to the new runtime to leverage the new features without having to redeveloper all their pages. This is where Silverlight 8.1 applications come in.

There is only minimal support within Visual Studio to support developers upgrading to Silverlight 8.1, allowing them to “Retarget to Windows Phone 8.1”.

image

Retargeting works well and typically your application will continue to run. However, in most cases you’ll want to maintain both a Silverlight 8.0 and 8.1 versions of your application. An alternative is to create a copy of your Silverlight 8.0 application and upgrade that – now you have two versions of your application that you have to support. Luckily this is an area where the new Shared project support, added to enable universal applications across Windows Phone and Windows, can be used to maintain code that is used by both a Silverlight 8.0 and 8.1 application (sort of Linked files on steroids).

Steps:

- Install the Shared Project Reference Manager (http://visualstudiogallery.msdn.microsoft.com/315c13a7-2787-4f57-bdf7-adae6ed54450) – this makes creating Shared Projects much easier

- Create a new Shared Project eg MyApplication.Shared

- Unload you Windows Phone project

- Edit your Windows Phone project file

- Add a Shared Project Reference via the right-click shortcut menu on your Windows Phone project (Note: for some reason adding a shared project reference isn’t supported for Windows Phone projects, so we need to do it the manual way)

- Add Import to end of project file which references the shared project file eg

<Import Project="..\MyApplication.Shared\MyApplication.Shared.projitems" Label="Shared" />

- Reload your Windows Phone project – you should see a reference to your Shared project under References node

image

- Move as many files as possible from your Windows Phone project into the Shared project

- Note that you may experience some of these issues:

> AppResources.resx doesn’t move easily. You’ll need to make sure that both the resx and the designer.cs file are moved and that the Build Action is correct (resx file should have a Build Action of Embedded Resource and a Custom Tool of PublicResXFileCodeGenerator). You also need to remove the “.Resources” from the name of the resource being loaded and the namespace.

> You need to keep any images referenced in the WMAppManifest.xml file in the Windows Phone project. This is ApplicationIcon.png and FlipCyleTileMedium.png by default

> You still need an App.xaml file in your Windows Phone project

- Check that your Windows Phone application builds and runs (fix any build errors!)

- In Windows Explorer take a copy of your Windows Phone application and rename the folder and project files eg MyApplication.SL81

- Add the copied project into the same solution

- Right click on the project you just added and select “Retarget to Windows Phone 8.1”. Your solution structure should now look similar to the following

image

- Build and run your new Windows Phone 8.1 application

The upshot after all this is that you have a Shared project where you can store shared files across your Windows Phone Silverlight 8.0 and 8.1 applications.

XAML and Databinding Debugging for Windows and Windows Phone

A question that came up today during the //learn/ event was how to debug data binding in Windows and Windows Phone projects.Normally I start by checking out the Output window – in most cases any issue with data binding is usually a naming issue, which will result in a bindingexpression path error in the Output window as follows:

Error: BindingExpression path error: 'test' property not found on 'App4.MainViewModel, App4, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. BindingExpression: Path='test' DataItem='App4.MainViewModel, App4, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'; target element is 'Windows.UI.Xaml.Controls.TextBlock' (Name='null'); target property is 'Text' (type 'String')

I was reminded that Xmlspy is a great tool for diagnosing XAML issues, as well as data binding expressions. I downloaded the latest version and was surprised to see that there is full support for all types of Windows Phone 8.1 applications. The only issue I saw was getting it to attach to Windows Phone applications but this was due to my firewall getting in the way. Here’s how you can check and fix this issue:

  • Open the XAML Spy Explorer window (View menu–> Other Windows –> XAML Spy Explorer)
  • Click on the “cog” icon in the window toolbar
  • Find the “Enable remote debugging” option and set it to Yes. You’ll be prompted to permit elevated privileges (I assume to configure firewall).

image 

Now you should be good to debug your application on the emulator/device. The XAML Spy Explorer window will automatically populate with information about your application

image

Note that you can debug much more than just XAML, including sensors, storage and package deployment information.

Debugging WebView in a Windows Phone application

In a previous post, Debugging Internet Explorer on Windows Phone 8.1, I covered how you could use the new debugging support for IE on Windows Phone to diagnose rendering issues. What I didn’t cover is how you could debug web pages when they’re hosted within an application using the WebView control.

As we’re now building for Windows XAML, we can actually use the same mechanism that’s available for Windows 8 applications (see http://www.jonathanantoine.com/2013/04/05/win8-xaml-app-how-to-debug-the-javascript-in-a-webview/ for instructions). All we need to do is change the Application process option under Debug.

image

Set this to Script and when you debug your XAML application Visual Studio will attach to the WebView allowing you to debug your script and DOM.

Debugging Internet Explorer on Windows Phone 8.1

The desktop version of Internet Explorer now has quite a good selection of developer tools available on any site by just pressing F12

image

Unfortunately on Windows Phone it’s been quite difficult to debug websites and so developers typically had to resort to alert(‘hello’); style debugging. With Update 2 for Visual Studio 2013 there is a new Debug menu item “Debug Windows Phone Internet Explorer”

image

This gives you the option to select the device/emulator and specify a launch site to debug.

image

The debugging experience is pretty cool as it’s actually in Visual Studio and includes the ability to set breakpoints and inspect variables.

image

Do also get the DOM Explorer

image

And the Javascript Console

image

This has got to make our jobs easier!

Speed up Blend for Visual Studio with TFS (Visual Studio Online) using a Firewall Rule

So for the longest time I’ve complained about how unusable Blend for Visual Studio is on projects that use TFS, specifically instances of TFS that are on the other side of the internet (yes, I’m looking at you http://visualstudio.com) . The issue is that every time you try to modify a file it goes off to TFS to check something…. I’m not quite sure what, but it hangs for a couple of seconds before deciding that you’re ok to make the change. This is particularly bad when you’re working with sample data.

It turns out there is a stupidly simple fix – don’t let Blend access the internet. Due credit to Dave who works with me at Built to Roam as he was the one that told me to just create a firewall rule.

Now, it’d show you some pictures of how to create the firewall rule using MMC but for some reason MMC crashes for me when I go to view the outbound rules. Anyhow, here’s the command for doing it via the command line:

netsh advfirewall firewall add rule name="Blend" dir=out action=block program="C:\Program Files (x86)\Microsoft Visual Studio 12.0\Blend\Blend.exe"

Blend will now complain when you first open a TFS connected project but there after it won’t miss a beat as you work with files as if there is no TFS connectivity.

Windows Phone 8.1 Emulator

In my previous post on Windows Phone 8.1 Developer Power Tools I looked at the developer power tools that are available from within Visual Studio. In this post we’ll look at the new Windows Phone 8.1 emulator and how it is an enabler for building better applications. The first thing to note is that there are a number of different emulator images available:

image

In this brave new world of varying screen sizes Windows Phone 8.1 departs from the fixed addressable width of 480 units. Instead each device has a scale factor which results in an effective resolution – in essence this means that two devices of the same size but differing hardware resolution will display the same amount of content, whereas two devices with the same resolution but differing size, will show more/less content depending on their relative size. What this means is that we now need emulators that not only vary in resolution but also in size.

image

Here you can see both the WVGA 4inch and the 1080p 6inch alongside each other – the beauty of it being in an emulator is that it can then be resized on the screen. The thing to notice is that the 1080p emulator has an additional column of tiles which will be a typical behaviour within applications when dealing with a higher effective resolution.

The next thing to note are the additional tools that are available. Here is a quick set of screenshots – we’ll go into more details on each of these in coming posts:

image image

image image

image image

 image image

Developing for Windows Phone 8.1 using XAML

By far the most common way to build Windows Phone applications is to use XAML and C# (or VB). In this case the XAML is a variant on Silverlight, which made it very easy for developers building Silverlight applications to switch across to building Windows Phone applications. 4 years on and the number of Silverlight developers has dropped (well at least the appeal of being a Silverlight developer has), and all the focus now is on becoming a Windows developer.

Unfortunately somewhere along the lines the Windows team decided that having three XAML frameworks (WPF, Silverlight and WP) wasn’t enough and that they needed to come up with another, only marginally different, framework. This we’ll refer to as Windows XAML.

With the announcements around Windows Phone 8.1 we’re entering a new time of convergence between phone and desktop applications where we can reuse not just the code (eg Portable Class Libraries and code file sharing) but also the XAML markup. This doesn’t come for free and relies on migrating our applications, or starting new applications, using Windows XAML instead of Silverlight.

So where does this leave us? What it means is that there are now three ways to develop for Windows Phone 8.1:

1) Windows Phone 8.0 Silverlight

Use this if you want maximum reach from a single application package; you don’t need or want to use any of the new platform features. This type of application will run on all Windows Phone 8.0 and 8.1 devices.

2) Windows Phone 8.1 Silverlight

By running the  “Retarget to Windows Phone 8.1” option after right-clicking on your application in Solution Explorer, your application will be migrated forward and will run against the new runtime. This means you can take advantage of some of the new platform features without having to redevelop your application. Whilst in most cases the retargeting process doesn’t modify the behaviour of your application, you will need to verify your application functionality before publishing the new version.

Once retargeted your application will only run on Windows Phone 8.1 devices, so it is recommended that you take a backup or a branch of your code and keep the 8.0 version alive to support those users who haven’t upgraded.

3) Windows Phone 8.1 Windows XAML

New applications, not wanting to maintain backward support for Windows Phone 8.0, can be created using Windows XAML. Ideally this would be all new applications as it allows for reuse across phone and tablet. The Universal projects concept introduced into Visual studio makes it easy to share code between projects, whilst still having platform specific functionality included in the “head” projects (ie the Windows and Windows Phone projects).

There is one thing that isn’t being highlighted is that each option has some limits on what you can and can’t do. 8.0 SL projects can’t access any of the new platform features. Windows XAML can’t do things like lock screen background provider….. it’s worth reading up on this before you make a decision

Windows Phone 8.1 Developer Power Tools

Last week at BUILD, Microsoft announced the availability of Visual Studio 2013 Update 2 RC, which includes the new Windows Phone 8.1 SDK.

I’m sure there will be a lot of blog posts talking about the new Universal project, the additional capabilities introduced in Windows Phone 8.1, Windows Phone XAML applications, the new application lifecycle model etc. I want to take a different approach and talk about some of the additional tools that come with the SDK.

One of the benefits Windows Phone development aligning with Windows app development is that more of the experiences along the development lifecycle will be similar. For example from the Project menu, Windows Phone developers now have the Store sub-menu with the ability to Create App Package.

image

One of the other additions is under the Tools menu, where there is a Windows Phone 8.1 sub-menu. This includes the Developer Power Tools, Developer Unlock and the Application Development tools. Whilst the last two are not new to Windows Phone development, they can now be reached from within Visual Studio.

image

The Developer Power Tools, not to be confused with the Windows Phone Power Tools, is a standalone tool which can be used to inspect what’s going on across either emulator or device. Help is available via MSDN

image

One of the most interesting thing about these tools is that you can start them, disconnect your device, put your application through its paces in real world scenarios, then reconnect and review the data at a later stage. For example, using the Performance Recorder you can check the data you want to record (eg CPU and Power) and hit Start. You can then disconnect the device, or in this case the emulator, open and run your application, and then reconnect and Stop the recording. This will prompt you to save a .etl file which includes all the data recorded.

image

The .etl file can then be opened using Windows Performance Analyzer (just double-click the file in Windows Explorer).

image

Hopefully these tools will help you track down issue in performance and usage of your application

Coded Design Time Data using Mvvmcross for Windows and Windows Phone

A question came in today regarding the use of design time data in conjunction with Mvvmcross. My initial response was “it just works” because I assumed that everyone does design time data in Blend….. and I’m still not sure why you won’t do this, since it promotes better design by giving designers the freedom to dictate the information architecture of each page. As it happens what they were really after was a way to plug in design time data that is generated in code. Without using mvvmcross this was relatively easy using a ViewModelLocator pattern – as part of serving up the view models, you could simply change the data source to be design time data when running in the dev tools. Because mvvmcross abstracts a lot of the work involved in associating pages with view models, it also means that it’s a bit harder to wire up coded design time data. In this post I’ll provide a summary (read “crude”) way I found to do this:

The assumption here is that your Mvvmcross project follows how Stuart describes a typical project in any of his getting started videos. Essentially this means a UI project (eg a Windows Phone project), that would contain your views (eg pages) and a Portable Class Library, that would contain your view models. There is also an App class in the PCL which is used to initialise mvvmcross. In this example we’re just going to work with the FirstView and its corresponding FirstViewModel but we’re going to add in support for a service which is used to populate data. Here’s the FirstViewModel:

public class FirstViewModel
    : MvxViewModel
{
    private IDataService Data { get; set; }

    public FirstViewModel(IDataService data)
    {
        Data = data;
    }

    public string Hello
    {
        get { return Data!=null?Data.TestData:"Missing"; }
    }
}

The IDataService has two implementations: DataService and DesignData, as illustrated here:

public interface IDataService
{
    string TestData { get; }
}

public class DesignData : IDataService
{
    public string TestData
    {
        get
        {
            return "Designtime";
        }
    }
}

public class DataService:IDataService
{
    public string TestData
    {
        get
        {
            return "Runtime";
        }
    }
}

At runtime we don’t need to worry about creating an instance of the DataService as it is automatically picked up by mvvmcross and injected into the FirstViewModel constructor. However, the DesignData is a little harder to use. At design time we somehow have to coerce mvvmcross to generate the FirstViewModel and populate it with an instance of DesignData. One option would be to go down the ViewModelLocator path again and use it only at design time to create our view model using design time data. However, this is rather clumsy given we have a perfectly good DI framework that we can leverage. The other thing is we’d have to continually update it to expose properties for each view model we want.

An alternative is to use a Factory pattern coupled with a Converter to dynamically create the appropriate view model. This is a bit of a chicken-and-egg thing to describe so I’ll start with how we wire it up in the UI project. Firstly, in the App.xaml we need to create both the Factory and Converter as resources:

<Application.Resources>
   <codedDesignTimeData:DesignFactory x:Key="Factory"/>
    <codedDesignTimeData:DesignTimeConverter x:Key="DesignConverter" />
</Application.Resources>

Next, in the page we set the d:DataContext (ie the design time data context) as follows:

<views:MvxPhonePage
    x:Class="CodedDesignTimeData.Views.FirstView"
    d:DataContext="{Binding Source={StaticResource Factory}, Converter={StaticResource DesignConverter}, ConverterParameter=FirstViewModel}"
    ... >

Let’s read through what this is saying – at design time, the DataContext for this page is going to be the Factory, passed through the Converter with the parameter “FirstViewModel”. As you can imagine what we’re really saying is that we’re asking the Factory to produce an instance of the FirstViewModel that we can data bind to.

Ok, so now we know what it’s saying, let’s look at the implementation of firstly the Converter, and then the Factory itself:

public class DesignTimeConverter:IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    { 
        var typeName = parameter as string;
        if (string.IsNullOrWhiteSpace(typeName)) return null;

        var factory = value as DesignFactory;
        return factory.Create(typeName);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

There isn’t much to the converter, it simply passes the parameter (ie the type of the view model to be created) into the Create method on the Factory object.

public class DesignFactory
{
    private Core.App app;
    public object Create(string typeName)
    {

        if (app==null)
        {
            MvxSimpleIoCContainer.Initialize();

                app = new Core.App();
            app.Initialize();

            Mvx.RegisterType<IDataService,DesignData>();
        }

        var type = app.FindViewModelTypeByName(typeName);

        if (type == null) return null;

        var req = MvxViewModelRequest.GetDefaultRequest(type);
        if (req == null) return null;
        var locator = app.FindViewModelLocator(req);
        if (locator == null) return null;

        IMvxViewModel vm;
        if (locator.TryLoad(type, null, null, out vm))
        {
            return vm;
        }

        return null;
    }
}

The factory is where all the smarts are. The first thing we do is make sure that mvvmcross is initialized – this is similar to what happens in your app. We then call FindViewModelTypeByName (see below for implementation) to exchange the view model type name with a reference to the actual type. Next we invoke the view model locator infrastructure within mvvmcross to retrieve an actual instance to the view model we’re after, which we then return (and is subsequently set as the DataContext for the page).

public Type FindViewModelTypeByName(string typeName)
{
    return CreatableTypes().FirstOrDefault(t => t.Name == typeName);
}

Ok, but wouldn’t is just be better to create an instance of the view model, once we have a reference to the type? No, because that view model may have any number of dependencies, which is why we need to rely on the DI framework provided by mvvmcross. You’ll notice I skipped over one quite important line, which was that we register the type DesignData as the implementation of IDataService we want to use. By default the Initialize method on our App class will look for types that end in “Service” and register them, which is why our DesignData doesn’t end in “Service”, but it also means we have to manually register it.

The upshot of this is that an instance of the DesignData class will be used to service up design time data for our view models in Blend. I hope this helps anyone working with mvvmcross.

Windows Phone Application Testing with Build it Beta

Yesterday I announced that Build it Beta is now public for Windows Phone app developers, but what is Build it Beta? Well it’s all about Windows Phone Application Testing. There are a number of existing mechanisms available to Windows Phone application developers but none of them offer the simplicity and ease of deployment as say TestFlight. Build it Beta fills that gap, providing a mechanism to allow any Windows Phone application to be deployed for testing to any Windows Phone 8 device*.

Build it Beta 

Firstly, why the name?

Well it’s a bit of a play on words – we’re always looking to build better apps and of course during development we often release “beta” versions of the app. Hence the origin of “Build it Better Beta”.

Next, how does it work?

Windows Phone 8 included the ability to deploy applications within the enterprise without going through the Windows Phone Store. This is referred to as enterprise deployment and involves signing an application (ie the packaged application file .xap) with an signing certificate. The same certificate needs to be distributed to the devices that the application is to be tested on. Then the signed xap can be installed on the devices either via code or by distributing the application to the device via email or via a url link. Build it Beta uses this mechanism to deliver a testing tool which eliminates the complexity for both developers and testers.

Ok,  so how do I get started?

The first step is to get Build it Beta from the Windows Phone Store, but we’ve got a simple set of setup instructions that will get you up and running in no time at all. If you’re not on your Windows Phone, scan the following QR with your Windows Phone (Search button, Vision app bar button) to jump straight to the instructions.

Once you’ve completed the setup, all you need to do is to start sending your .xap files to upload @ builditbeta.com. Make sure you send them from the same email address that you registered with when setting up Build it Beta. We’ll ingest your xap and send you a confirmation email. You should also get a toast notification on your Windows Phone device letting you know that a new version of your application is available for testing. Click on the link in the email, or tap on the toast notification to download and install the signed version of your application.

* Build it Beta relies on enterprise deployment to install applications. This is a feature that was introduced with Windows Phone 8 which means Build it Beta cannot install applications to earlier versions of the Windows Phone operating system. If you need to deploy applications for testing on earlier versions of Windows Phone you can do this using the Windows Phone Store Beta process.

Building Charming Apps for Windows and Windows Phone

Fellow MVP and owner of In the Hand, Peter Foot has published a number of helper classes for developers targeting both Windows and Windows Phone. I particularly love that these enable developers to “build charming apps!”

Charming ApplicationModel
Charming Display
Charming NFC Share
Charming Popups
Charming Search
Charming Settings
Charming Share
Charming Storage

Get them directly from NuGet or visit the CodePlex site for more information.

http://charming.codeplex.com/

Aligning Characters and Spacing in Windows 8.1

When designing applications for Windows Phone we spend a lot of time aligning the left edge of virtually everything to either each other or to the imaginary grid drawn over the page. Unfortunately the SDK doesn’t make life easy for us as the TextBlock element doesn’t automatically trim white space on the left of the contents. The net effect is illustrated in the left of the following image where the “a” and “b” aren’t left aligned, despite being offset by exactly the same amount from the left edge of the page.

image

Windows 8.1 includes the OpticalMarginAlignment property which you can set to TrimSideBearings in order to remove excess whitespace. The net effect is shown in the right side of the image where the “a” and “b” are now left aligned.

Intercepting DataContext Change in Windows and Windows Phone

Often when working with UserControls you need to wire/unwire logic when the DataContext of the control changes (eg it’s used on a page and the viewmodel which is bound to the page flows into the UserControl as the DataContext). Unfortunately prior to Windows 8.1 there wasn’t an easy way to do this. In Windows 8.1 you can do the following in order to hook up to the DataContextChanged event handler

public class TestControl : UserControl
{
    public TestControl()
    {
        DataContextChanged += TestControl_DataContextChanged;
    }

    void TestControl_DataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
    {
        // Do stuff with the new Data Context
    }
}

So, how would you do this prior to Windows 8.1 and for Windows Phone? Well, one option, and I’m not saying this is the only option, is to create a different dependency property and connect it using data binding. For example:

public class TestControl : UserControl

   public object CustomDataContext
    {
        get { return GetValue(CustomDataContextProperty); }
        set { SetValue(CustomDataContextProperty, value); }
    }

   public static readonly DependencyProperty CustomDataContextProperty =
        DependencyProperty.Register("CustomDataContext", typeof(object), typeof(TestControl), new PropertyMetadata(null,DataContextChanged));

    private static void DataContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // Do stuff with the new Data Context
    }
}

And when you use this control, you’ll need to data bind to the CustomDataContext property:

<local:TestControl CustomDataContext="{Binding}"/>

The “{Binding}” without a path simply means that the current DataContext for the control will be passed in. You’re then free to do whatever you want with the real DataContext as you can be assured it would have been set at this point.

Organisations that discard TFS in favour of Git are throwing out the baby with the bath water.

A number of clients that I’ve worked with over the past couple of years have made the decision to abandon their internally hosted Team Foundation Server (TFS) in favour of a Git. Some have decided that they’re going to host their own Git repository; others use it in the cloud. Unfortunately most of them have been suckered into using Git without understanding what they do or don’t get as part of the package.

The first thing to observe is that the first couple of versions of TFS were a nightmare as they were overly complex to setup and even worse to manage. Luckily I was never game enough to go down that path as at the time I was working of an instance of SVN running on a VM with 500MG of RAM  on a Mini-PC box sitting under my desk (and btw it ran like a dream with checkins taking fractions of a second even from the other side of the planet). Unfortunately some organisations spent years fighting TFS handing it off to traditional ops people and expecting them to know how to manage it.

For a lot of developers the two step checkin process of committing locally and then pushing to a repository is just a waste of cycles and they won’t get much benefit from the peer-to-peer nature of Git. Those passionate about Git will argue that this is because they haven’t invested enough time into Git to learn how to use it to its full extent. I’d counter this by indicating that if you’re spending that long working with Git, then you’re not writing enough code and that your process is broken (most likely checking in too infrequently resulting in lots of large merges). My early arguments against Git were that it was unnecessarily complex as everything had to be done via a command line – really, really really, in this day in age, we have to use a command line to do checkins??? Luckily there are now several UI alternatives available for those who don’t want to see a command prompt.

With these points aside (this isn’t a post on why you should/shouldn’t use Git) it’s important to recognise that Git is really only about source control; source control makes up a very small, yet integrated, part of TFS. Particularly with the move to the cloud (check out http://visualstudio.com) TFS has undergone a transformation with new features rolling out hot of the press. Not only does it do source control, it also does task and iteration management, build automation, testing, and even team rooms for conversing with remote team members on a project. All of which are integrated so you can see what code was written to fix a bug, who broke the build and what they changed, and even get notification in the team room when a build has succeeded. This level of integration is completely missing from Git.

So you have to wonder, if these organisations are not using TFS, what do they use as a replacement for managing projects. The answer is a sad combination of email and disparate tools kit bootcamp and jira. The lack of integration means that requirements, tasks and bugs are often loss into the email abyss; code is modified and no-one knows who or why the changes were made and builds either don’t exist or are managed completely independently. Of course, in some cases someone in the team realises theses pieces of software aren’t working together, so they cobble together an integration piece which is so brittle that the build breaks more frequently because of their patchwork solution, than it does because someone legitimately broke the build.

The upshot of all this is that if you haven’t tried Visual Studio Online, I’d suggest now is the right time to take another look at TFS. Sign up, and I’m sure you’ll be pleasantly surprised….. oh, and did I mention you can opt to use Git for you source code!

Data Exchange for Application Extensibility on Windows Phone and Windows

Both Windows and Windows Phone support launching applications based on file extensions or via a custom uri protocol. This is the equivalent of “open in” capability that other platforms have and it is a fundamental mechanism for sharing data from one application to another. For example you might have a dropbox application which can list various files but doesn’t provide a mechanism for opening or editing all possible file types. Instead when a user clicks on a file to open it, the application can simply attempt to launch the file, allowing the platform to pass off the file to the appropriate application. This is implemented by taking a copy of the file and passing it to the destination app. Unfortunately this then means that the view/editing application can’t save it back to dropbox. The round-about way to save the changes is to then launch the file, this time with the file being picked up by dropbox.

What’s interesting is that this is expressly prohibited by the Windows Store App certification requirements. Point 3.1 states that applications can’t implement bi-directional data exchange:

image

My view is that this clause was written by a completely different team (probably a security “expert”) to the one that actually implemented file/uri handling and doesn’t really understand why they were implemented in the first place. In Windows you can implement Share contracts but this is not really a great way to data exchange between apps – it works well for “share to social” or similar scenarios. Take the Facebook Login for Windows Phone this uses bi-directional data flow to authenticate users via Facebook for applications wanting to connect to Facebook (similar to the way iOS works for Facebook auth). With the current Windows Store requirements I don’t see this as being possible.

 

References

Auto-launching apps using file and URI associations for Windows Phone 8

Auto-launching with file and URI associations Windows Store apps

Non-Blocking Initialization Code to run at Startup on Windows Phone

One of the challenges often faced by developers is that they have code that needs to run at startup. This code typically has to run before any page begins to load its content; it has to support deep - linking, so shouldn’t be page dependent; and should never block the UI (which if done for long enough would cause the app to crash). In this post I’ll show you one way to achieve this – I’m sure there are plenty of other options.

In the constructor for the application make a call to your initialization method. This initialization method will return almost instantaneously since it simply spawns another thread.

public App()
{
    // Standard init code for a Windows Phone app ...

    // This can be called here since all it does is pass off to another thread for the long running tasks to run.
    // If this code requires the app to be further in the lifecycle, then you may need to
    // move to launching/activating event handlers
    InitCodeThatTakeAWhile();

}

And now for the initialization method. As mentioned, the first thing it does is to spawn another thread using Task.Run. Despite warnings from Resharper we do not await this call, since this would prevent the app from initializing correctly. Inside the Run we can do whatever we want to initialize the application. When it’s done, it simply calls Set on the ManualResetEvent.

private static readonly ManualResetEvent initWaiter = new ManualResetEvent(false);
private async void InitCodeThatTakeAWhile()
{
    // DON'T wait, or you'll block the caller
    Task.Run(async () =>
    {
        // Put init code here - can take as long as you want
        await Task.Delay(10000);
        initWaiter.Set();
    });
}

The App class also exposes a method which is used to wait for the ManualResetEvent to be set. It does this on a separate thread, thus allowing any UI code to continue to execute.

public  static async Task WaitForInitToFinish()
{
    // Switch to a different thread to wait, thereby allowing UI to process
    await Task.Run(() =>
    {
        initWaiter.WaitOne();
    });
}

Lastly, we need to invoke the wait method. This should be done on any page which is, or could be, used as a startup or launch page for the application. In fact, you could create a base class and call the WaitForInitToFinish method by overriding the OnNavigtedTo method.

protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    // Change to loading states....
    LoadingText.Text = "Loading....";

    // Wait for init to complete
    await App.WaitForInitToFinish();

    // Now do page init code
    LoadingText.Text = "Loaded";
}

This strategy is useful for triggering startup logic, whilst ensuring the UI doesn’t block

Data Validation and Visual States for Windows Phone and Windows

One of the developers we’ve been working with recently suggested incorporating the INotifyDataError interface into some of the view models on a particular project. As a lot of the applications we typically  work on are more consumption style applications I haven’t seen the need to add complex data validation logic; where we do need to validate one or two values we typically just have a different visual state that represents when the user hasn’t correctly filled in the required fields.

I just had a quick hunt and found http://dotnet-redzone.blogspot.com.au/2012/12/windows-phone-8-easy-and-intuitive-way.html. This post is a great starting point for implementing visual states into a Windows Phone project. A number of controls support data validation. For example the TextBox has a ValidationStates visual state group, with states for valid and invalid data. The default template doesn’t specify what these states look like but it would be easy to modify the template to provide a visual indicator when data doesn’t validate.

Modifying the validation states for a control is fine for individual controls but if you need to modify the visual state for the rest of the page you’d need to capture the ErrorsChanged event and change the visual state of the page.

One of the biggest weaknesses of the data binding framework for both Windows and Windows Phone is that there isn’t a built in mechanism for changing visual states from within a view model. There are some solutions, such as data triggers or raising an even that is captured by the page and converted into a state change. These could be combined with the ErrorsChanged event in order to build a more versatile data validation framework.