Draw Your Own Pie Chart dynamically

In this tutorial, I’ll show you how to draw your own pie chart just using lines and a list of data items. The code itself is in C#, but the concept can be used on any platform that has a drawing library and ArcSegments.

You can view the entire solution in this GitHub Gist. Okay, let’s get started!

Setting Up

The first thing you’ll need to understand is how the platform’s drawing library makes arcs. In this code, I’ll be using RadPath from Telerik UI for Xamarin most libraries work the same way. RadPath lets you use a custom Geometry which has RadArcSegment object, which has helpful StartAngle and SweepAngle properties.

Let’s start with the data model, with simple Title and Value properties:

public class ChartDataPoint
{
    public string Title { get; set; }
    public double Value { get; set; }
}

Next, let’s create a list that is populated with some activities to represent a 24 hour period.

var dataPoints = new List<ChartDataPoint>
{
    new ChartDataPoint { Title = "Work", Value = 9 },
    new ChartDataPoint { Title = "Commute", Value = 1.5 },
    new ChartDataPoint { Title = "Leisure", Value = 6 },
    new ChartDataPoint { Title = "Sleep", Value = 7.5 },
};

Finally, to finish the setup, create a list of colors we can use for the pie slices.

var colors = new List<Color>
{
    Color.FromHex("#BAB65A"),
    Color.FromHex("#6196D1"),
    Color.FromHex("#3D4268"),
    Color.FromHex("#8A56E2"),
};

Part 1 – Creating the Slices

Now that we have some items, lets move on to generating and drawing the slices. First, we’ll create a container to put the pie and legend into. A Grid is convenient option because we can have two rows, one for the pie and one for the legend.

// Root container to hold the chart and any legend
var container = new Grid();
container.RowDefinitions.Add(new RowDefinition { Height = new GridLength(3, GridUnitType.Star) });
container.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });

Now we can start calulating the slice sizes, to do this, we need a total value to get a percentage of that total. We also need a variable to hold the current position on the 360 degree arc where the slices are rendered.

// Sum up all the values to be displayed
var totalValue = dataPoints.Sum(d => d.Value);

// Variable to keep track of where each slice ended.
double currentPosition = 0;

Now for the guts of the operation. We need iterate over the data points and create the arc segments using the data point’s Value property. The code comments will guide you through what each line does, in a nustshell here’s the lifecycle

  • Calculate the data item’s percentage of the total sum
  • Use that percentage to get what percent of 360 degree pie that slice needs
  • Create the RadArcSegment using the current position for the StartAngle and the angle percentage as the SweepAngle
  • Construct the RadPath using the ArgSegment’s geometry and a color from the colors list
// Iterate over the data points to create slices.
for (int i = 0; i < dataPoints.Count; i++)
{
    // Determine the what percentage that data item's value is of the whole
    double slicePercentage = dataPoints[i].Value / totalValue;

    // Calculate the sweep angle using that percentage amount.
    double sweep = slicePercentage * 360;

    // Create the ArcSegment using the current position and sweep
    var segment = new RadArcSegment
    {
        Center = new Point(0.5, 0.5),
        Size = new Size(1, 1),
        StartAngle = currentPosition,
        SweepAngle = sweep,
    };

    // Important - Calculate the last segment's ending angle in order to have a valid start angle for the next loop.
    currentPosition = currentPosition + sweep - 360;

    // Prepare the required PathFigure and add the ArcSegment
    var figure = new RadPathFigure { StartPoint = new Point(0.5, 0.5) };
    figure.Segments.Add(segment);

    // Create the PathGeometry and add the PathFigure
    var geometry = new RadPathGeometry();
    geometry.Figures.Add(figure);

    // Construct the RadPath
    // - Select a Fill color from the brushes parameter (important: use a modulus to wrap to the beginning)
    // - Use the Geometry created from the value
    var slice = new RadPath
    {
        Fill = new RadSolidColorBrush(colors[i % colors.Count]),
        Geometry = geometry,
        HorizontalOptions = LayoutOptions.Center,
        VerticalOptions = LayoutOptions.Center,
        WidthRequest = 100,
        HeightRequest = 100,
        Margin = new Thickness(0, 20, 0, 0)
    };

    // This isn't necessary, but added for completion.
    Grid.SetRow(slice, 0);

    // Finally, add it to the container.
    container.Children.Add(slice);
}

At this point, you now have a full 360 degree chart, with colored slices for each of the data points representing their percentage of the whole.

Part 2 – Creating the Legend

The next phase of the operation is to create the legend. This needs to create text for each slice, as well as a marker that matches the same color of that slice. This could have been done in the same loop as creating the slice, but having a separate loop lets you decide to use a legend or not.

Again, we iterate over the data points. This time we use the Title property of the data point to create the text. To match the color, we use the same modulus to get index and assign it to a RadBorder that creates a thick bar underneath the text.

// Create a horizontal StackLayout to hold the legend items
var legendPanel = new StackLayout
{
    Orientation = StackOrientation.Horizontal,
    HorizontalOptions = LayoutOptions.Center,
    VerticalOptions = LayoutOptions.Center,
    Margin = new Thickness(0, 16, 0, 0),
    Spacing = 5
};

// Iterate over the data points and create a legend item with a matching color
for (int i = 0; i < dataPoints.Count; i++)
{
    // Use a RadBorder with only a bottom thickness and match the color to the slice
    var legendItem = new RadBorder
    {
        BorderColor = colors[i % colors.Count],
        BorderThickness = new Thickness(0, 0, 0, 2)
    };

    // Create a Label for each data point and use the Title property
    var label = new Label
    {
        Text = dataPoints[i].Title,
        FontSize = 12,
        Margin = new Thickness(0, 0, 0, 2),
        TextColor = Color.DimGray
    };

    legendItem.Content = label;

    legendPanel.Children.Add(legendItem);
}

// Insert the legend panel in the root container's 2nd row.
Grid.SetRow(legendPanel, 1);
container.Children.Add(legendPanel);

The last thing to do is add the entire container to the UI. In this example, I’m just setting the entire page’s content to the container Grid..

this.Content = container;

Wrapping Up

I hope this is useful for those times when you need ultimate control over rendering of a chart. If you need more complex setup, I recommend the RadPieChart itself, which is far more feature complete than drawing a few arcs 🙂

Talk to the View


There are many scenarios where a UI component might not have a Command or bindable property available for certain features that you need to access from the view model. There is a simple, but powerful, thing you can do to allow this and not break MVVM or testing capability, leverage the Interface.

Scenario

Let’s imagine the scenario where we have a special ListView control that has a HighlightItem method that can only be called with a direct reference to that control. There isn’t a Command or DependencyProperty (aka BindableProperty in Xamarin.Forms) alternative, so it has to be done in the code behind.

To keep this simple, here’s the page XAML…

<Page x:Class="MyPage">
    <Page.DataContext>
        <MyPageViewModel x:Name="ViewModel" />
    </Page.DataContext>

    <SpecialListView x:Name="MyListView" />
</Page>

…and here is the page code behind.

public partial class MyPage : Page
{
    public MyPage()
    {
        InitializeComponent();

        // The only way to use HighlightItem method is in the code-behind
        MyListView.HighlightItem(itemToHighlight);
    }
}

As you can see, the HighlightItem method has to be used in the code behind because it has a reference to ‘MyListView’. However, you need to use it in the view model, like this:

public class MyPageViewModel
{
    private void PleaseHighlightItemNow()
    {
        // But, you need to highlight the item from view model
    }
}

Solution

One solution for this is to define an interface.

public interface IHighlightableView
{
    void Highlight(object item);
}

With this, you can add a property to the view model and invoke the method:

public class MyPageViewModel
{
    public IHighlightableView View { get; set; }

    private void PleaseHighlightItem()
    {
        // Call the method on the interface!
        View?.Highlight(itemToHighlight);
    }
}

Now, the interface can be implemented on the page to complete the circle

public partial class MyPage : Page, IHighlightableView
{
    public MyPage()
    {
        InitializeComponent();

        // Assign this page instance to the view model
        ViewModel.View = this;
    }

    private void Highlight(object itemToHighlight)
    {
       // Now you can directly use the UI component's method
        MyListView.HighlightItem(itemToHighlight);
    }
}

Summary

This is a simple approach that will work if you don’t want to (or are not allowed to) use an existing MVVM framework’s built-in DependencyInjection and IoC features. Enjoy!

Using PowerShell to Install an SDK in a DevOps Build Pipeline

I have an open source UWP project that relies on the Ad SDK and Engagement SDK to be installed to Visual Studio. This normally isn’t a problem, because you can just run the MSI on your PC (see installation instructions here and here).

I decided to move the project into DevOps so that I get some of that CI/CD goodness to build and publish new releases automatically to the Microsoft Store. However, there was a problem, when trying to build the project in a DevOps build pipeline, you’ll get the following error:

This means that the Hosted VS2017 Agent that DevOps uses to build a UWP project doesn’t have the Extensions SDKs installed. I have two choices to move forward:

  • Use a private Agent (this uses your local PC to build the project via a server connection )
  • Find a way to install the SDK into the Hosted agent

I did try the first option. I set up the Windows Agent on my Surface Book, connected it to DevOps and it works nicely (this is why you see that early successful build early in the first screenshot above). However, it’s not a solution for me because it means my PC has to be always on and network-connected.

My friend, and MVP peer, Oren Novotny mentioned that you can actually use a PowerShell script to download the MSI file and install it to the Hosted VS2017, this was the break I was looking for!

To implement this, I downloaded the MSI files I needed from the Visual Studio Marketplace and put them into an Azure Blob. It provides me with two reliable URLs to download the files in the PowerShell script.

Next, I wrote the very simple script. It has two phases: a download phase and an install phase (with a quiet switch “/q”). Here’s what that looks like:

# Predefined Variables
$adSdkUrl = "https://dvlup.blob.core.windows.net/general-app-files/MSIs/MicrosoftAdvertisingSDK.msi"
 $servicesSdkUrl = "https://dvlup.blob.core.windows.net/general-app-files/MSIs/MicrosoftStoreServicesSDK.msi"
 $adSdkPath = Join-Path $env:TEMP "MicrosoftAdvertisingSDK.msi"
 $servicesSdkPath = Join-Path $env:TEMP "MicrosoftStoreServicesSDK.msi"

# Download the files to local temp folder
 Write-Output "downloading $adSdkUrl…"
 Invoke-WebRequest -Uri $adSdkUrl -OutFile $adSDKPath
 Write-Output "downloading $servicesSdkUrl…"
 Invoke-WebRequest -Uri $servicesSdkUrl -OutFile $servicesSdkPath

# Install the SDKs (use the "qn" flag to install silently)
 Write-Output "installing $adSdkPath…"
 Start-Process $adSdkPath -ArgumentList "/q" -Wait
 Write-Output "installing $servicesSdkPath…"
 Start-Process $servicesSdkPath -ArgumentList "/q" -Wait

Next, you need to add a Powershell step to your DevOps Build pipeline and paste in the script. Here’s a screenshot to help guide you:

Now, when the build is triggered, it will download and install the missing SDKs before building the project! Here’s the result of that build step in the Hosted agent’s console:

I hope this post finds you as soon as you need help. It took me several days, a dozen different documentation articles (some are hyperlinked above) and my MVP peers to find a good simple solution that didn’t require my PC .

LoginDialog for easy Live SDK OAuth

Almost every developer I speak with agrees that getting a nicely working OAuth flow can be difficult. After much trial and error, I’ve built a UWP ContentDialog that makes this easy and has built-in refresh token support.

Using the LoginDialog

This is very simple to use, when the app launches, instantiate the dialog by passing your Live SDK ClientID and let the LoginDialog do the heavy lifting:

// Pass your app's OAuth ClientId (sometimes called an AppId)
var loginDialog = new LoginDialog("YourAppClientId");

// *** Perform login **** //
// Case 1 - If the user was previously signed in, there is a refresh_token stored and no user-entered credentials are needed.
// Case 2 - If the access token fails, or if it's the first sign-in, the user will see a popup to enter credentials.
await loginDialog.SignInAsync();

if(!string.IsNullOrEmpty(loginDialog.Authentication))
{
    // This will be the access token you can use for API calls.
    var accessToken = loginDialog.Authentication;

    // Make your API calls with the accessToken, for example:
    var user = await apiService.GetUSerProfileAsync(accessToken);
}

This works just like a MessageDialog, but instead will show a WebView for the user to sign in, or automatically sign them in silently if they were previously logged in.

Get the full source code in this GitHub Gist.

See this tweet for a video of what it looks like when it automatically logs you in and here’s a screenshot what it looks like when the dialog needs to appear:

Dialog Visible

Operational Summary

Explaining OAuth 2.0 is outside the scope of this article, but to summarize there are a couple round trip to the authentication endpoints.

  1. Load the sign-in landing page and the user signs in with their credentials.
  2. In the redirect after successful sign-in, you’ll get an access_token and a refresh_token for that authenticated user.

The access_token is what is used in all of your API calls that verifies the application is operating on the behalf of that user. The access_token expires after a preset amount of time (e.g. 60 minutes), after which time you have to request another access_token.

Here is where the refresh_token comes in handy. You could go back to step #1 above, but this would require the user re-enter their credentials. Instead, you can just use the refresh_token  you already have for the user to get a new access_token without ever interrupting them to show a WebView.

This is what the LoginDialog does for you, when you call SignInAsync() the following happens:

  • Checks to see if there is a refresh_token stored locally. If there isn’t one, show the WebView and have the user sign in for the first time.
  • If there is a refresh_token stored locally, then use that to automatically get a new access_token without showing the dialog

Since this is general OAuth 2.0 workflow, you could probably adapt the dialog to work for other OAuth 2 endpoints by changing the dialog’s _signInUri, _signOutUri and _redirectUrl values.

Wrapping Up

The LoginDialog lets you have the least amount of interruption to the user while quickly getting an access token for your API use.

The RS5 Update Resources and Tutorials

My friends at Microsoft have put together an amazing compilation of resources of all the new stuff available in the Windows 10 October 2018 Update (aka RS5). Below is a list of some of those resources relevant to developers and enthusiasts, enjoy!

SDK Downloads

New Samples and Sample Updates

  • XAML Hosting API Sample uses the new XAML hosting API and C++/WinRT to demonstrate usage of XAML controls within a Win32 application.
  • Customer Orders Database Sample has been updated to use the new Data Grid and other new controls in RS5.
  • Photo Editor C++/WinRT Sample has been updated to build with the RS5 SDK and to use the new single_threaded_observable_vector function to create an IObservableVector for data binding. An additional performance update will be coming out in a couple weeks.
  • Data binding and MVVM is a new topic that was identified as a need based on the Code First program. The topic describes the benefits of using the MVVM design pattern and how it has been applied to the sample apps.

Videos

Application Developer Resources

Driver Developer Resources

Error XF001: Xamarin.Forms targets have been imported multiple times

If you’re in the process of updating a Xamarin.Forms app to a more modern style project set up (NET Standard 2.0, PackageReference, etc), you may get the following error.

 

Error XF001: Xamarin.Forms targets have been imported multiple times. Please check your project file and remove the duplicate import(s).

 

This can be because of the move to using PackageReference for your NuGet packages and a simple fix awaits you.

  1. Close Visual Studio and navigate to the Solution in File Explorer
  2. Delete the hidden .vs folder
  3. Go into each affected project sub folder and delete the following files; project_name.nuget.props and project_name.nuget.targets
  4. Open the solution in Visual Studio, do a Clean and Rebuild, 

 

You should no longer see the error and be able to deploy.

 

 

 

 

Custom Events and Xamarin.Forms Effect

This post will walk you through setting up a Xamarin Platform Effect and show you how to wire up an event handler so you can leverage native APIs in the case that the Xamarin.Forms wrapper doesn’t yet have. For this example, I’ll use the Telerik UI for Xamarin RadCalendar.

tl;dr Full source code on GitHub here.

I get frequently asked how to enable RangeSelection (aka Multiple Selection) for the RadCalendar. The native platform calendar controls all have Range Selection available, so we only need to create a  Platform Effect to access that native feature.

Note: If you’re not familiar with Effects, I recommend visiting this article first to understand the fundamentals (it’s a quick tutorial).

The main things I need are:

  • DateTime StartDate
  • DateTime EndDate
  • DateRangeChangedEventArgs (class)
  • DateRangeChanged (event)
  • DateRangeChanged (delegate)

I’ll walk you through the different parts below, you can also see just the relevant classes in this GitHub Gist or get everything in this GitHub repo

Class Library

First, let’s get the event args out of the way because we’ll need this defined before writing the Effect.

(view code) Portable/Effects/DateRangeChangedEventArgs.cs

2018-07-16_2020

Now we can move on to the Effect definition that lives in the class library project.  The class defines the rest of items I listed above, I’ve called out how the event is invoked, thus subscribers to the vent will have their event handlers executed.

(view code) Portable/Effects/RangeSelectionEffect.Forms.cs

2018-07-16_2020

With this set up , we can add the Effect to the Xamarin.Forms XAML RadCalendar instance:

(view code) Portable/MainPage.xaml

2018-07-16_2033

Code behind, this is just to set the start and end dates to test the Effect:

(view code) Portable/MainPage.xaml.cs

2018-07-16_2035

But we can’t run it just yet. It’s time to implement the native Effect classes., it’s where the magic happens. I’ll go through each platform separately instead of hitting you over the head with it all at once.

UWP

The calendar control for UWP is the UI for UWP RadCalendar.  In the documentation, we can see it supports multiple selection by flipping the SelectionMode flag to Multiple.

The next thing to consider is how to actually set the date range. This is done using the SelectedDateRange property to an instance of CalendarDateRange. This is what we needed the event for! You’ll see that when the Effect is Attached to the control

(view code) UWP/Effects/RangeSelectionEffect.Uwp.cs

2018-07-16_2018

iOS

For iOS the native control is a UI for Xamarin.iOS TKCalendar and in a similar fashion as UWP, we find the Selection modes to support Range Selection.

Notice we need to use the native control’s selection property and convert from DateTime to NSDate

(view code) iOS/Effects/RangeSelectionEffect.iOS.cs

2018-07-16_2029

Android

And finally, the same approach is used for the native Android calendar, UI for Xamarin.Android RadCalendarView.

Notice we need to use the native control’s selection property and convert from DateTime to Java Calendar

(view code) Android/Effects/RangeSelectionEffect.Android.cs

2018-07-16_2030

And that’s it! All three platform’s Calendar control now will show range selection.

Disclaimer

This isn’t production-ready code, it’s proof of concept and there are no defensive techniques in place (i.e. try/catch). I wanted to keep it as simple as possible to focus on the concepts.

If you want to use the code for your app, I’m happy I could help (MIT license). Just please don’t copy-paste it all and call it a day, then ping me on Twitter later and say “it’s broken!”.  The native platform logic should be inside try catch blocks and I would make sure the DateTime conversions are accurate for your needs.

Enjoy!

 

 

 

Epic Build 2018 Playlists

Your one-stop shop for Microsoft Build 2018 sessions, slide decks, post links, keynotes and much more.

Living Document Note:

These Playlists will continue to be reordered and updated in real time as new content becomes available. However, the links will always remain the same and you can refresh the playlist page to get any updated ordering/content.

Migrating from PCLStorage to .NET Standard 2.0

If you’re a Xamarin Forms developer, you’ve likely used PCLStorage (or other Dependency Service) to interact with the target platform’s file system in the portable class library’s code. However, since November 2017, Xamarin.Forms now uses a .NET Standard 2.0 class library and PCLStorage is no longer supported.

System.IO.File

This isn’t a problem because in .NET Core 2.0 you now have access to System.IO.File’s GetFolderPath and SpecialFolder methods (see System.IO.File in .NET Core 2.0 docs).

Thus, you can get a path to the app’s local folder (the one that the app can save to) without having to write a Dependency Service (which is what PCLStorage does) by using:

var localFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);

 

IMPORTANT: Make sure you always use Path.Combine to create the file path because different platforms use different path separators

var filePath = Path.Combine(LocalFolder, "notes.txt");

 

With a reference to the file path,  you can now access the file. For example reading the text:

var notes = File.ReadAllText(filePath);

Functional Demo

As a very simple example, I created a couple extension methods for Stream and Byte[] in the below FileExtensions class.

To test it, I created a ContentPage that downloads an image, saves it using the extension method and set a FileImageSource to confirm that it’s a file (instead of just using a StreamImageSource).

 

https://gist.github.com/LanceMcCarthy/693ab82aa498cadf75e9fe778c4242ad

 

Note that the extension methods are very basic and shouldn’t be used in production as-is (i.e. no defensive programming code).

Here is the result at runtime on UWP:

2018-04-19_1134

Windows 10 on ARM: Day-One Developer Experience

I was given the honor of having early access to Windows 10 on ARM (WoA) so that I could chronicle the experience and provide you with tips to ensure that your development experience is smooth. I’ll go through a list of potential issues you might encounter, along my fix for each.

What this post is:

This article is intended to be a quick guide on how to set up the device so that you can deploy and debug your apps. I will be writing this from a UWP developer’s perspective, sharing the experience of deploying and debugging this real time video effects test app.

Several of my fellow MVPs also got a device and will be writing posts about their experiences as well. Some articles will be UWP specific and others win32 specific, see the Additional Resources section at the bottom of this post.

What this post is not:

This will not be a “product review” style post about the device or the OS itself. I will say this: I am very impressed, it’s just Windows 10 and I really wouldn’t be able to tell it was on ARM until I realized that it’s been 2 weeks since I last charged it 🙂

Okay, enough intro talk, let’s get our hands dirty. First, a little primer on x86 emulation, an explanation of how Microsoft was able to get Windows on ARM and how your app will work.

How Windows on ARM works

Chances are you’re using a 32 bit application right now, but your PC is running a 64 bit version of Windows running on an x64 CPU. How does an application with 32 bit instructions work on a CPU that expects 64 bit instructions? This is accomplished using x86 emulation, provided by the WOW64 layer in Windows (WOW64 stands for Windows 32bit on Windows 64bit).

To create Windows on ARM, Microsoft ported Windows 10 to ARM64! The kernel, shell, in-box drivers and in-box apps all run native on ARM. What about your apps? Windows on ARM has x86 Win32 emulation!

The WOW abstraction layer, in concert with a custom x86-to-ARM emulator and CHPE dlls (x86 assemblies with ARM64 code in them, pronounced “chip-ee”), your x86 application can run in an emulated process on an ARM CPU.

Here’s a diagram to better explain it

Post7

Some key features

  • The x86 app win32 app runs unmodified
  • The app will installs and run like it does any other PC
  • The x86 instructions are translated to ARM64 at runtime and they get cached so that future app runs are faster!

Application Support

Windows on ARM supports ARM32 and x86 applications

  • Store apps (ARM32 preferred, x86 supported)
  • Win 32 apps (x86 supported, x64 not supported).

Tip: If your Store application has an ARM32 package available, it will be installed and will run natively as this provides the best user experience. Where possible, make sure all of your Store apps also have an ARM32 package.

If you’re not sure how to do this, when you go to package your app, you’ll see three checkboxes, make sure ARM is selected:

Post8

For win32 apps, you can use NGEN (see #2 under the General Tips section below).

Limitations

There are some limitations at this time

  • No x64 emulation support
  • No kernel mode support
  • Apps that rely on drivers may not work (the driver developers should start updating their drivers for ARM support)
  • Apps that inject code into Windows processes won’t work

For more info about Windows on ARM, take a look at Kevin Gallo’s Community Standup video here and the Build 2017 session from Hari and Arun here.

Okay, now with a high level look at how WoA works, let’s dig into my experience and how I hope it helps you

Familiar Ground – Remote Debugging

If you’ve used Visual Studio’s remote debugging tools before, for example with Hololens or Windows IoT, then you’ll feel right at home. The process is essentially the same, but with a couple things to keep an eye out for when you’re first getting started.

The first thing you need to do is enable Developer Mode in the device’s PC Settings > Updates and Security > For Developers page. Not only so that you can deploy apps to the device, but also to enable the Remote Debugging tools.

Here’s a screenshot of the PC Settings page:

Post2

However, you may not see this option, which brings me to my first point.

Potential Issue #1

My device came with Windows 10 S out of the box, this means that I will not see a “For Developers” item on the Settings > Update and Security page (screenshot above).

Fix

Upgrade the OS. I used a product key for Windows 10 Pro in the Settings > System > About page, but you can use whichever option is available to you.

Post1

After updating you’ll now see the Developer Mode option on the For Developers page, toggle that to move forward. Enabling this will trigger a download an installation of a Developer Mode package that contains the Remote Debugging Tools.

Potential Issue #2

You may experience an issue where the developer mode package didn’t install correctly, you should see a “Remote Debugging Tools Installed” success message. If you didn’t or see an error message, this means that you will not have the tools on that machine and you’ll get frustrated when trying to deploy from Visual Studio.

Fix

Download and install the tools manually, you can find the download here. Alternatively, you can copy over the tools from your dev machine if you’re familiar with the steps, but installing the tools is the most straightforward option: run and done.

Targeting the Remote Device

If you’re not familiar with using the Remote Debugger, I strongly urge you to read this Microsoft documentation article, but let’s go through the main steps.

Changing Target Device to Remote Machine

If you open your application’s Properties page in Visual Studio, and switch to the Debugging tab, you’ll see that you have a Target Device drop down.

Post3

Switch that to Remote Device, then the “Find…” button on the right will become enabled. After clicking the Find… button, you’ll be presented with the following UI:

Post6

Now you have an opportunity to select a remote device, but you will most likely see that the ARM PC isn’t showing as an available device to target.

There are two ways to solve this, use the device’s IP address or let “Auto Detected” find it for you. In both cases, the device needs to be visible on the network, but Auto Detected is far better because it helps with setting Authentication Mode.

Potential Issue #3

No devices are in the Auto Detected list or you can’t connect using IP address.

Fix

You need to make sure that the both the development PC and the ARM PC need to be on the same network and that Network Discovery is enabled.

The quickest way that I like to do this (there are other ways), is just to use File Explorer and selecting “Network” in the pane and follow the prompts.. Easy Button style. Here are some screenshots to guide you:

Post4

Once you click the OK button, File Explorer will show a yellow bar at the top:

Post5

Click that bar and follow the prompts, it will ask you to make the network you’re on a Private Network (that’s my preferred option as it’s the safest). You’ll now see that the PC will scan the network, finding other devices and listing them in File Explorer. Go ahead and close File Explorer now that it has done its job.

NOTE: If you need to, repeat this process for your development PC.

Connecting

With both PCs visible on the Network, reopen the Remote Connections dialog window again (using the “Find…” button) and check the Auto-Detected list for the ARM PC. Select it, then follow the steps to connect and pair it.

Potential Issue #4

You’re not able to see the device in the Auto-Detected list, and you’ve hit Refresh button to scan again.

Fix

You can instead use the ARM device’s IP address and select “NONE” for the authentication option. When selecting this route, you’ll be shown a PIN number to pair to Visual Studio.

I haven’t been able to get Universal Authentication to work with manual IP address connection yet, but my follow MVP testers have and their blogs posts may touch on this further.

Congrats, now you’re ready to deploy!

Debugging & Deploying

Before you click F5 (or that shiny green start debugging button) for the first time, let’s review another issue you will encounter that might you might miss. I didn’t see it the first time because I was looking at Visual Studio instead of the device.

Potential Issue #5

When debugging, you do not see any runtime analytics / debugger metrics in Visual Studio Diagnostic Tools window (usually at the top right):

2018-02-25_11-01-15

Fix

Keep an eye on the ARM device for an elevated permissions UAP prompt the first time you deploy. You may only see a TaskBar yellow-flashing icon and not a full screen prompt, click the icon to see the prompt and allow it.

General Tips

You’re going to be quite surprised at how well everything just works, In several cases, I found my apps worked faster on the ARM device than my dev PC!

Tip 1 – Failure to launch

When remote deploy does’t work, look at the Visual Studio build output window. Close to the end of the build output, you’ll probably see a reason why the deploy failed.

You’ll most likely see one of these errors (click the link to view the respective troubleshooting article):

Issue 2 – Slow first launch

When using an x86 application on Windows 10 on ARM, the first time an app launches it will be a little slower. This is because the x86 to ARM translation will occur the first time, but the result is cached on disk so the future launches are significantly faster.

Also, while waiting for that first launch, don’t try to relaunch it again. Otherwise, you’ll end up opening multiple instances of the app that will further slow things down (it can take 5-30 seconds depending on how much translation needs to be done). I’ve communicated my feedback to Microsoft that there should be some sort of indication that the app is starting up (e.g. a flashing taskbar icon).

Workarounds:

  • If the app is a Store app, provide an ARM package so that it runs natively and doesn’t need emulation.
  • If the app is a win32 app, try using NGEN.

Wrapping Up

This post will be a living document for a little while, I’ll come back and update the post with anything new I find, and continue to share my tips with you. I’ll be sharing my fellow MVP’s posts as they become, see them under the Additional Resources paragraph below.

I hope you enjoy running your x86 apps on an ARM device as much as I have, it’s a wonderful future for mobility and battery life where you don’t have to sacrifice your library of applications because of a CPU’s architecture.

  • Anything I can help with?
  • Are you stuck trying to deploy your app?

Leave a comment below or reach out to me on Twitter here (please remember that I can only answer development-specific questions).

Additional Resources

I will update this list as more posts from my fellow MVPs, and Microsoft documentation, becomes available.

MVP Posts

Microsoft Articles