For a while now I’ve wanted to do something in UWP (Universal Windows Platform).
UWP always gives me the “uncanny valley” sort of feeling; it looks like WPF and looks like a standard Windows .NET application, but it also has that feeling on the unknown about it. To illustrate what I mean, UWP application compile to an EXE, but anyone used to Windows programming will probably double click on the EXE and find that Windows responds with a message box stating “This application can only run in the context of an app container”.
We’ll cover this soon enough, but let’s start our adventure with the classic Hello World type example and look at the basic parts of a UWP application and using Visual Studio 2017 to run the application etc.
Versions etc.
First off, I’m using Windows 10.0.15063.0 and Visual Studio 2017, version 15.2 (26430.16). I state this upfront because I’ve found books/posts talking about previous versions telling us to expect this file and this dialog when creating a new project, so what you see may differ from what I describe here, depending upon your versions.
Creating our project
In Visual Studio, carry out the following
- File | New Project
- Visual C# | Windows Universal
- Select Blank App (Universal Windows)
- Name it HelloWorld
- You’ll be prompted to choose a target version and minimum version, leave these as defaulted for now
Navigating the project
Properties
Within the Properties section is the usual AssemblyInfo.cs, but also the Default.rd.xml. This is used to contain runtime directives (hence .rd.). This allows us to specify elements within our program that are available for reflection.
Reference
Unlike non-UWP applications, the References have only two items (excluding the Analyzers). Microsoft.NETCore.UniversalWindowsPlatform and Universal Windows.
Assets
By default the Assets folder contains seven png images. Including store logo and splash screen. These are templates (if you like) for your own images. Every one of the images is a square with a cross in it – so you’ll know pretty quickly if you’ve not supplied an image/logo/splash screen for some area.
App.xaml
Like WPF, we have an App.xaml (and ofcourse the App.xaml.cs code behind). The code behind has a fair bit more code within it, unlike WPF. Default code is there for us to handle state loading during the application launch, a point to save state when the application is suspended etc. Also, unlike WPF, the MainWindow (in this case MainPage) is navigated to via the OnLaunched code as opposed to being declared in the App.xaml file like WPF.
HelloWorld_TemporaryKey.pfx
A temporary key is created for us. As UWP is aimed at being downloaded and installed from the Windows Store (or side loaded) this requires the application to be signed, hence we’re given the starting point for this.
MainPage.xaml
MainPage.xaml and it’s code behind contain minimal XAML and code (like a standard WPF control). UWP tends to class these controls as Pages (reminds me of Silverlight).
Package.appxmanifest
Finally we come to the application manifest. This allows us to set up things like the application’s display name, the rotations supported (for tablet/phone type devices). We can assign our assets to specific scenarios, such as for tiles, app. icons and so on. We’ll also need to declare what capabilities the application needs access to. Sort of standard mobile phone development requirements, i.e. this application will require Bluetooth etc.
Note: It’s best to reduce the capabilities to the bare minimum required as some user’s may prefer to lock down the access an application has.
So if we want to run the application, you’ll notice that (at least on my install of Visual Studio) there the run button on the toolbar with Local Machine shown (mine’s also defaulted to x86 instruction set). From the drop down we also have Simulator, Remote Machine, Device as well as a bunch of Mobile Emulators of different screen sizes.
The emulators obviously allow us to view our application on a mobile phone or tablet like sized device.
Remote Machine allows us to run the application remotely, so for example on a Windows tablet, but without needing to install it directly etc.
The simulator is a virtual device or maybe better thought of as a remote desktop. The odd thing is that you’re really remote desktop-ing into your own machine, so changes to the simulator affect your machine.
So, let’s choose Local Machine, then we’re doing the equivalent of running a “standard” windows application. You’ll notice a square with a cross in it displayed, this is the SplashScreen.scale-200.png supplied by the project template within our Assets folder. Change this and then re-run to confirm.
Once running our application is, as expected, a blank application, but before we move onto actually writing some code/designing the UI, when we ran the application Visual Studio actually installed the application for us in the Start Menu, under Recently Added you should see HelloWorld (if you followed my naming for the application). If you attempt the run the EXE within the build folder, you’ll get the message box stating “This application can only run in the context of an app container”, however from the Start Menu, the application will be correctly run from a container.
Finally for this section, when you run the application via Visual Studio you’ll see four icons on your main page, these include tools to view the visual tree of a selected item at runtime and enable selected option, display layout adorners and a track focused element tool.
These, by default, are hidden outside of the debugger, but we can also hide within the debugger experience by selecting Tools | Options | Debugging | General, then locate Enable UI Debugging Tools for XAML and deselect this option.
The splash screen
As mentioned previously, we define the splash screen image (or edit the existing) within the Assets, as this is assigned via the manifest. UWP automatically displays the splash screen for us over the application Window and within App.xaml.cs, the OnLaunched method, when Window.Current.Activate() is called, the splash screen will be removed (obviously it will not immediately happen as the Windows message will need to be sent through, but it’s at this point the UWP application then “properly” starts your application. Hence within OnLaunched, is the place to restore state or setup anything prior to the splash screen being removed.
Note: Like Windows Services, your application is expected to start within a certain amount of time or it’s perceived as failing to start. I’ve read this time is approximately 15 seconds. So you’ll need to be a little more creative if loading your application takes longer than this, i.e. run code on a non-blocking thread or simply lazy load state etc.