I built this little application called “Tile a File” quite a while ago for Windows 8.0 In a little ‘downtime’ over Xmas I thought I’d retarget that application to Windows 8.1 as there were a few things that needed changing in the light of the changes that Windows 8.1 brings.
It took me a little while to find the source code for the project but, after a little searching, I found the right place in TFS, branched my project such as to leave a Windows 8.0 version that I can maintain in the future and then began the work of updating my project to Windows 8.1
Tile-A-File is built as 3 projects in Visual Studio. There’s a main application and a Windows RT component and they both make use of a little common code in a library so the project structure looks like;
Retargeting Projects and Resolving References
The first thing to do was to put my faith into Visual Studio and ask it to retarget my projects to Windows 8.1 in terms of references and so on. It’s not difficult to press the button
That seems to go ok (as far as I could tell);
but it highlighted a couple of problems for me in that I’d made use of 2 libraries in building Tile-A-File as below;
One was the Callisto library by Tim Heuer which I’d made use of because I needed to provide a Settings flyout in my application and in Windows 8.0 the XAML framework didn’t provide one so I’d used Tim’s. The other was the WriteableBitmapEx project which I use to generate bitmaps on the fly.
When I updated these packages from Nuget I hit a minor problem of the compiler not knowing the difference between Tim’s SettingsFlyout in Callisto.Controls class and the one now present in Windows.UI.Xaml.Controls because I had a source file which had using statements for both of those namespaces.
Just to get my code building I added a quick using statement;
using TimSettingsFlyout = Callisto.Controls.SettingsFlyout;
and then replaced all my SettingsFlyout code with TimSettingsFlyout code and had my code back and building for 8.1 knowing that I would later go back and change this code to use the Windows.UI.Xaml.Controls.SettingsFlyout and possibly remove Callisto altogether unless I was using it for something else.
Updating the Version Number
The next thing I figured I’d do is change my version number. I have some settings code which reads this from the app assembly itself via reflection and displays it along with a bunch of other information which might also need changing;
but I figured changing the version number was a good idea and, as far as I know, it’s important to set a Windows 8.1 version to be above any possibly Windows 8.0 version number for an application so I figured I’d set my version number here ( which is not the same as the version number in the store ) to be version 184.108.40.206 as that seemed to leave enough space for the Windows 8.0 code base.
[assembly: AssemblyCopyright("Copyright © 2014")] [assembly: AssemblyVersion("220.127.116.11")] [assembly: AssemblyFileVersion("18.104.22.168")]
Windows 8.1 adds 2 new tile sizes to the ones on Windows 8.0 – namely the 70×70 tile and the 310×310 tile so it was time to make some of those. My original logos were “designed” using Expression Design and I tend to use one .design file for each logo and check them into TFS so to make these new tile sizes I just copied existing tiles and resized them.
I’m not sure that a user would ever use a large (i.e. 310×310) tile for this particular app but my thought is usually to at least give people a choice and so I included one here.
I noticed that I’d obviously been too lazy to properly size all my tile logos for the 140, 180 and (in Windows 8.1) 80 percent scaling so my manifest looked like this;
Looking across my assets it would seem that I was missing;
- 2 logos for the store at 140 and 180 scaling
- 7 30×30 logos at 80, 140, 180 and then 4 target size scales
- 3 310×310 logos
- 3 310×150 logos
- 3 150×150 logos
- 3 70×70 logos
- 2 splashscreen logos
that’s 21 additional images to drop into the project. It took a little while but I added them all in. In all cases, I’m no great artist so I simply took the vector art that I had at the 100%, scaled it appropriately in Expression Design and then exported it directly to PNG at that size. About an hour later, I had all my images.
Dealing With Snapped View
In the original Tile-A-File for Windows 8.0, Snapped View was a bit of a problem.
On the one hand, an application was required to implement snapped view but on the other hand the API to raise the file selection dialog wasn’t allowed while in snapped view so there wasn’t much that an application like Tile A File could do and so the UI asked the user to unsnap the app.
On Windows 8.1, Snapped View is gone and so I set the minimum width of the application to be 500px in the manifest;
In the original app, I’d done some abstraction to write a plug-in service which detected when the application switched between full-screen-landscape, full-screen-portrait, snapped, filled views and fired events which ultimately reached the XAML view which would react by changing into a particular visual state via the Visual State Manager.
This code is now mostly redundant and so I took away and XAML state animations relating to Snapped/Filled and then modified the code so that it was no longer relying on Windows.UI.ViewManagement.ApplicationView.Value which returns an ApplicationViewState value. That ApplicationViewState is now deprecated so I changed my code such that it now relies only on Windows.UI.ViewManagement.ApplicationViewOrientation to determine whether it should display a portrait UI or a landscape one and for the minimal UI that this app displays there’s not much of a difference either way.
Providing the Right Launcher Options
The idea of the Tile A File app is to let the user create a tile on their Start Screen for a file like a PowerPoint presentation.
That tile is actually a secondary tile for the Tile A File app and when it’s tapped, the app runs and realises that it is being launched from a secondary tile and so it asks the system to launch the file in question (the PowerPoint presentation e.g.). This requires the Tile-A-File app to be able to access that file across invocations of the app.
On Windows 8.1 the way in which the system deals with an app that uses Windows.System.Launcher.LaunchFileAsync has changed. In Windows 8.0 the launched file (e.g. the PowerPoint) would take over the whole screen but on Windows 8.1 it launches alongside the original app by default.
That makes for a bad experience with Tile A File so I needed to make a small modification to the LauncherOptions passed to the LaunchFileAsync call to make sure that the launched file takes over all of the screen. A simple change but one that’s necessary for this app.
Once the Tile A File app has launched the file in question it makes a decision as to whether it should exit based on whether the app was running prior to launching from a secondary tile. Exiting a Windows app is against guidance but I feel it’s almost valid for this specific app because the user has tapped on a tile which to them represents one of their files that they want to launch (e.g. a PowerPoint) so they probably expect 1 app to end up running (PowerPoint) rather than 2 (PowerPoint + Tile A File).
I don’t think that the way I do this provides a ‘perfect’ experience on Windows 8.1 though because while the Tile a File process does seem to exit and the app doesn’t show up in the apps listed by using ALT+TAB, it does continue to show up in the apps listed by WINDOWS+TAB.
Providing the Right Tile Options
The main thing that Tile-A-File does as an application is to create tiles (from files!) and so it’s important that the app does the best it can around creating tiles and those APIs have changed from Windows 8.0 to Windows 8.1.
In the 8.0 code, the app creates a secondary tile by creating a new SecondaryTile object and then setting its WideLogo and Logo to be wide (310×150 px) and square (150×150 px) and also by setting a few other options such as the launch argument.
In Windows 8.1 the APIs for accessing SecondaryTile.Logo and similar properties are deprecated so code like this snippet below;
SecondaryTile newTile = new SecondaryTile( this._appStateProvider.AppState.GetIdAsStringToken()); newTile.Arguments = this._appStateProvider.AppState.GetIdAsStringToken(); newTile.DisplayName = this._appStateProvider.AppState.FileName; newTile.ForegroundText = SettingsManagement.TileForegroundText; // This Logo property is deprecated. newTile.Logo = this._appStateProvider.AppState.ThumbnailImageUri;
is living on borrowed time.
The system has also changed in the way that it displays a choice of tile sizes to the user when an application is trying to create a secondary tile. Even though the code only creates a square and a wide tile the system offers the user 3 choices of tile size;
Which is nice but it’d be nice if my code also created a 310×310 tile in case the user wanted to make a big tile for their file. In the example above, the app has created an image for the tile based on the thumbnail that it gets for the file in question from the system but the app also offers the user a chance to change the image to any image that they might want to pick from the file system and that might be a place where the user wants a bigger tile.
I played around a little with my image generation code such that it explicitly created all four sizes of tile image and also my tile generation code such that it used the new VisualElements property of the SecondaryTile class and filled in all four sizes of tile image and, coupled with my existing settings pane which lets the user choose the colours for their tile;
that should mean that the user can now create whatever size of tile they want in whatever colour with whatever image. One area where I could perhaps improve this is to handle the new SecondaryTile.VisualElementsRequested event to offer the user more choices than just 4 tiles of the same colour but of different sizes. In that event handler I could generate a bunch more tiles of varying colours and offer them to the user but I’ve left that for (perhaps) a future version.
Coming back to settings, as I said at the start of this post this app is using the Callisto toolkit to provide its Settings pane and, while it’s all working perfectly, that’s one dependency that I could remove by taking away my use of SettingsFlyout from Callisto and using the one that’s now built into .NET Framework 4.5.1 for Windows 8.1 Store apps.
It seemed pretty easy to move from one version of SettingsFlyout to another – the only properties that I was using that seemed to clash a little were the HeaderText->Title and HeaderBrush->HeaderBackground changes and also the property IsOpen is gone and replaced by a Show() and a ShowIndependent() method.
In all, it took about 2-3 minutes to make changes here. The only other “problem” I had was that I think my SettingsFlyout was using the Light theme when I had ‘designed’ the controls which sit in there to rely on a Dark theme. Because there’s a new property on FrameworkElement in .NET 4.5.1 (called RequestedTheme) it was a very easy change to make in order to get that sorted out.
Uploading to the Store
With all of those changes made, I ran the new app through the WACK test and it passed ok so I thought I’d see if I could submit to the Store. The app package is uploaded;
and I noticed the build process had split out the artefacts here into a couple of resource bundles to go alongside the main package which should make for a slightly better install process.
With that, it’s time to click submit and see if the Store people are happy to approve the app….