Following on from this growing series of posts;
Windows 10 UWP–Migrating a Windows 8.1 App (Part 1 of N where N tends to infinity)
I felt that it was time to take a look at my main page which under the Windows 8.x version of the app displayed a GridView of captured QR codes of different types (the app supports unknown/telephone/URL/email/VCard/Mecard formats). It used to display something like this;
with captured codes somewhat arbitrarily grouped into [today/yesterday/back-in-the-day] groupings which can then be seen in semantic zoom;
and it’s possible to play around with selection here, selecting all, none of the codes and then removing them, acting upon them (e.g. acting on a telephone number will invoke the tel: scheme) and also sharing them;
and sharing does a ‘best efforts’ type of approach – here’s an example of a VCard/MeCard (not sure which) shared into the mail app;
All in all, this isn’t huge functionality but there’s a little bit to it and I’d like to get all/most of it back working in the Windows 10 version of the app so I began work on it.
Moving the Page to Windows 10
The first thing that I realised was that this page (and others in the app) were still derived from LayoutAwarePage which I think was in the Windows 8.0 templates back in the old days.
This base class did some work around enabling snapped/fill views and it also did some work around navigation and state management.
I figured that I didn’t want it any more and so removed it and made my pages derive from Page. No doubt, that broke some functionality that’ll need to be fixed later. Beyond this, changing this base class pointed out some code that was now redundant around starting/stopping the monitoring of window width changes and attempting to use those to drive visual state transitions into snapped/filled views which were starting to be on their way out in Windows 8.1 and are pretty much redundant in the light of Windows 10. That code went in the bin.
The next decision that I made was that I was going to get rid of the SemanticZoom. Frankly, I probably included it in the original build of the app just to experiment with it and because it seemed like ‘the thing to do’ at the time whereas now with Windows 10 I’m not sure that I see many of the built in apps showcasing semantic zoom any more – I don’t see it in the Finance app or the News app. Consequently, SemanticZoom was also gone.
I also removed the grouping of my data – again, I don’t see this so much in Windows 10 applications and I don’t really see the need for me to use it here and so I took it out of the UI and my view models. I’m not sure that any real user of this app will ever have so many QR codes that they will want to display them in groups and, particularly, not in the arbitrary groups that some developer (me) decided were appropriate.
That lost me a bunch of XAML and some code and I lost a little more in that the tweaks that I looked to have made to the GridView’s ItemsPanel and HeaderTemplate no longer seemed necessary in the light of my other changes so I took those away and ended up with a GridView that is closer to ‘out of the box’ than I had back in Windows 8.x.
After some fiddling around with item templates and item container styles, I ended up with this presentation of the data on Windows 10;
It’s very similar to what I had on Windows 8.x but it’s certainly not the same and, rather than grouping the QR codes based on their capture time, I’ve offered a simple ComboBox which allows the user to sort by date or by the type of QR code that they are looking at.
In terms of the command buttons at the bottom of the screen, for the moment I’ve got rid of the AppBar that I previously had (it wasn’t a CommandBar as it was written for 8.0) and the commands indicated by the red arrows below are simply buttons presented in a StackPanel;
Those commands are context sensitive in the sense that they change as the GridView’s selection changes and selection was on area where I hit a bit of a snag.
I’m not sure if it’s just a property that I’m missing but back on Windows 8.x if you used a GridView it was possible for an item to be selected/unselected without that item being ‘clicked’ – you could do a swipe against the direction of the control’s scroll direction and the item would become selected without firing an item click event (even if the IsItemClickEnabled property was set ‘True’).
In Windows 10, I’ve yet to figure out how to do this and so I was finding that I couldn’t select any of my items without invoking those items. On my QR codes, that means invoking the default action for a URL, phone number, email address, etc.
In order to try and work around that, I’ve taken to setting the GridView.IsItemClickEnabled False and adding a specific button into the UI to invoke the item rather than to select it;
and that’s quite different from what I had in Windows 8.x – the whole surface of the item is now used for selection and this one small area is used for invocation.
Returning to the set of commands at the bottom of the Window, if there are items selected then some more options appear;
with the highlighted one being ‘Share’.
Prior to Windows 10, an app didn’t need to have UI for ‘Share’ because that was found on the Charms Bar but, in 10, that Charms Bar has gone and so an app needs to have a way of invoking Share if it wants to offer it.
This is the UI that I’ve used for it – just a button that appears whenever there are items selected in my GridView. Beyond that, the code that I already had to implement the Share charm seems to continue to work just fine on Windows 10 so it was only the additional button that I had to put in place here to bring that code back to life.
It does feel a little ‘wrong’ to put this button at the bottom of the Windows as most apps seem to place it at the top like the Finance app does here;
However, at the moment if I put Share up at the top of my UI then it’ll be the only thing up there and so, for now, that feels like overkill.
The original 8.0 app had the notion of a Snapped View, a Filled View and a Full-Screen landscape/portrait view. In the Snapped View, it replaced the GridView which is the main list here with a narrow ListView and, for Windows 10, I’ve still got that ListView around.
However, rather than show/hide the ListView depending on whether the Window is ‘snapped’ or not I’m now using AdaptiveTriggers to drive visual state transitions based on the width of the window. The states look something like;
<VisualStateGroup> <VisualState x:Name="wide"> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="{StaticResource narrowWindowWidth}" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="listView.Visibility" Value="Collapsed" /> <Setter Target="gridView.Visibility" Value="Visible" /> </VisualState.Setters> </VisualState> <VisualState x:Name="narrow"> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="0" /> </VisualState.StateTriggers> <VisualState.Setters> <Setter Target="listView.Visibility" Value="Visible" /> <Setter Target="gridView.Visibility" Value="Collapsed" /> </VisualState.Setters> </VisualState> </VisualStateGroup>
and you can see that, at the time of writing, I’m just toggling visibility values on my ListView and my GridView depending on the window being narrower/wider than a constant value (540px at the moment).
After some tweaking of ListView ItemTemplates and ItemContainerStyles I got my ListView to this state;
and I’m not yet sure whether I’m happy with that but it functions for the moment and it’s simpler than what I had in 8.x.
While producing this view, I found myself constantly puzzling over what I would do with this view on a phone as I don’t think it’s very phone friendly and I had to make the conscious decision of putting those choices to one side while trying to get things working on the PC first. It’s my intention to make this app span phones and PCs when I put it back into the Store but, for now, I’m going to mostly ignore phone and return to it once I have the app working on the PC.
With that, I have the main page of the app largely working on Windows 10 and I perhaps spent around 3-4 hours getting it done with quite a bit of that (as ever) being lost to tweaking templates. One reason for that would be that I didn’t build in decent design-time data support when I build the app and so now I’m paying for that
The next step here would be for me to revisit the app’s camera capture page and I have great hopes for making some big changes to that code based on;
- What I saw in the //Build 2015 Session: Developing Powerful Camera Apps
- There being a WinRT port of the ZXing QR code library available
I’m hoping that a lot of the code that I wrote for camera capture in the 8.x version of the app will be able to be scrapped and I’ll get a better result for less code on Windows 10. Let’s see…