While we all know that Test Driven Development (TDD) is a good idea, in practice it’s not always viable. It could be a time constraint, a resource issue or the project just doesn’t warrant it.
While TDD may sometimes be an option, unit tests themselves should really be considered to be a must. They will save you a lot of time in the long run and while they may not prevent you from going grey, ask me how I know, they will reduce your stress levels when bugs raise their ugly heads.
So, whether you write your tests before you write the code or vice-versa, if you are developing production code you really should write tests to cover it.
Now, one of the requirements for unit testing is the ability to mock out a components dependencies so that you are only testing the component itself.
Normally you would use the Dependancy Injection pattern to help develop loosely coupled systems but Xamarin.Forms has a few components which can be a fly in the ointment – one of these is the MessagingCenter.
MessagingCenter allows you to send messages from one component to another using the publish-subscribe pattern to do so in a loosely coupled manner.
It’s build into Xamarin.Forms and is very easy to use;
On one side of the process you will send (publish) your message;
If you have used ASP.NET in recent years you will probably be familiar with the appSettings.jsonfile and it’s associated, build-specific transformations, e.g. appSettings.development.json and appSettings.release.json.
Essentially these allow developers to define multiple configuration settings which will be swapped out based on the build configuration in play. Common settings are stored in the main appSettings.json file while, for instance, API Endpoint Urls for development and production deployments are stored in the development and release files.
At compile-time any values specified in the deployment version of the file overwrite those in the common version.
Simple – works well and we use it all the time without thinking about it. But what about Xamarin.Forms – it doesn’t have such a mehanism out of the box so how do we achieve this and prevent accidently publishing an app to the App/Play Stores which are pointing to your development/staging servers?
Previously I have tried a number of approaches and while they mainly worked there were always shortcomings which meant that I couldn’t really rely on them.
One used a pre-deployment step in Visual Studio to copy the appropriate file, based on the build configuration, from one location to another where it would be picked up by the applications startup code. This worked fine when running on Windows but not when building on the Mac (using Visual Studio for Mac) because it uses the cp command and not copy.
Yes, I could have created an alias from copy to cp but what about when I want to configure a Continuous Integration build on Azure DevOps?
Another approach had me creating Operating System specific script files, .bat on Windows and .sh on the Mac, and again using a pre-build task to run the appropriate script (executing the extension-less command would run the appropriate version on each platform). But passing arguments for the build configuration was clunky and again Azure DevOps pipelines didn’t really seem to want to play ball – maybe Microsoft is a bit cautious about letting anyone execute scripts on their Azure servers 😉
Well, after deploying and testing the wrong version of an app onto my phone and scratching my head for twenty minutes I decided enough was enough and using the first approach above as a base I have come up with a simple mechanism which does the job.
The (my) Solution
The solution I’m running with requires a configuration file to be created for each build configuration, e.g. Debug and Release (by default), which are configured as ‘Embedded Resources’.
A static property is added to the App class which implements the Singleton pattern to load and return an instance of a class that represents the contents of the configuration file – I’m using Newtonsoft.Json to deserialise the file and hydrate an instance of the class.
Add some Conditional Compilation Symbols to the mix and we are just about there.
I’ve created a basic Xamarin.Forms project using Visual Studio 2019 Community Edition, stripped out all the default stuff and added in a single Content Page, ViewModel, Class and two Configuration Files:
The appsettings.debug.json file has the following content:
You probably don’t need any clues to the content of the other version 😉
The only thing to remember here is to ensure that you set the ‘Build Action’ for these files as ‘Embedded Resource’:
The AppSettings.cs class is a simple POCO with a single property which corresponds to the json files:
Now, when a Xamarin.Forms app starts up the App class is, for all intents and purposes, the entry point and is generally available to the Content Pages throughout the app. So this is a good place to expose our AppSettings:
Notice how the property getter will instantiate the AppSettings instance if it is not already in place.
Also notice the use of the conditional compilation statements (#if .. #else .. #endif) in the LoadAppSettings method. This is where the ‘magic’ happens. I know that some people may shy away from this approach but this is the way I’ve gone for now.
Basically the LoadAppSettings method will read in the specified file depending on which build configuration is in play at the time. The file is deserialised into an instance of AppSettings and the local variable updated.
As the .json files are Embedded Resources we can address them using their fully qualified names, noting that the namespace is made up of the overall Namespace (AppSettingsPoc), the folder name containing the files (Configuration) and the actual filenames. Yours will be different for sure – just remember how it’s comprised.
For the conditional compilation to work we need to specify the appropriate symbols (the ‘RELEASE’ text in the above code).
To do this, Right-Click on the shared project (the one with the App.xaml file) and select ‘Properties’:
Select the ‘Build’ tab from the left hand side and set the configuration to ‘Release’ if it’s not already.
In the ‘Conditional Compilation Symbols’ field enter ‘RELEASE’ (or whatever you want to call it – just match it up with what you use in the App.xaml.cs file). If there are other values already present then tag this new one to the end, delimiting it with a semi-colon.
So, we have the configuration files, we are loading them and making the available to the Application. Now we just need to consume the data and for this I’m using a ViewModel, HomeViewModel.cs, which will be the Binding Context to our Page.
The ViewModel class is another simple POCO with a single property which reads the WelcomeText from the AppSettings instance via the App class:
Finally, we just need to bind this property to a UI element on our Page:
Notice that on line 10 in the above markup I’m specifying the BindingContext to an instance of the HomeViewModel. As with many things in Xamarin.Forms, there are numerous ways of acheiving this.
The label has a Text property which I’ve bound to the WelcomeText property (which will be on the ViewModel remember) and that’s about it.
If I run the app in Debug mode I will see the message as read from the appsettings.debug.json file. Run it in Release mode and it will be the message from the appsettings.release.json file:
The solution presented above requires a small amount of setup and then it pretty much fire-and-forget. If you need a new setting then update your AppSettings.cs class, add the values to your .json files and you are good to go.
Need a new build configuration, say Staging? No problem. Just create the new .json file (remembering to set it’s build action as ‘Embedded Resource’), add a new ‘STAGING’ symbol to the project properties, update the LoadAppSettings method to check for it and you are done. Simple as that really.
Now, some may say that Conditional Compilation is bad and that using Reflection is the work of the Devil. But frankly – I’m quite pragmatic about these things and if it works and doesn’t have a dreadful code smell then I’m not going to lose too much sleep over that.
Have I changed my mind about withdrawing support for this app – no, I haven’t. Essentially my hand has been forced by Google’s recent decision to deprecate some of the functionality I was using to fetch nearby places as part of the ‘Add New Station’ wizard as well as requiring 64 bit support – the latter being little more than a checkbox and nothing that most users will ever notice.
Removal of the Places Picker
Prior to the update, when adding a new station a user could specify the location in one of two ways;
Select from a list of locations provided by the Google Places API and flagged as ‘Gas Stations’
Open a ‘Place Picker’ in the form of a map and drop a pin on the desired location
It is the second option which is now going away – and there is nothing I can do about it. Google are pulling it and that’s that.
The Place Picker was added as I noticed that a nearby ‘Flogas’ centre, where you could buy cylinders of LPG and also refill your vehicles tank, was not on the list returned by Google Places. Using the Picker it was possible to zoom and pan in order to locate the desired location. It was also useful if you weren’t actually present at the station you wanted to add, i.e. it wasn’t nearby!
So where does that leave users (apart from heading to the Play Store to complain and leave a 1 star review!) – well, if the desired location is not displayed in the list then they will need to head over to the website and add the station there. Not as convenient as using the app maybe but not rocket science either.
But why bother if the app is ‘Dead’?
Well, after viewing some in app analytics I found that on average around 25 new stations were added, via the app, each month so there is a chance that users would bump up against this problem when trying to open the Place Picker – chances are that the app could simply crash out.
If the ‘Add New Station’ feature wasn’t being used I’d probably just have removed the menu option and have done with it.
But enough users were using it so I set aside a couple of hours to investigate and remove the Place Picker and it’s associated code while leaving the ‘Nearby List’ in place – even if it will only contain locations flagged by Google Places as being ‘Gas Stations’.
In this instance the required update was not too onerous – just a couple of hours of work really, however, this may not always be the case.
Android is always evolving and Google could well make changes to other areas of functionality that could adversely affect the application and require a lot more development effort, e.g. forcing a migration to the new version of the Maps API.
In that instance it would probably the end of the road for the app and it would either have to hobble along or be pulled from the Play Store altogether.
I receive a lot of SPAM regarding the FillLPG mobile app, mainly offering to increase my install numbers and ratings, but today new approach appeared in my Inbox.
I was reviewing your app FillLPG – LPG Station Finder, and it looks great. But it appears the app does not support new Android Pie. Without it, more than half of the users cannot use the app properly. I am an app developer and I can update your app in a couple of days if you want.
It may not be obvious but this is just SPAM, sent by a bot and I doubt that anyone called ‘Jon’ is actually involved in the process, let alone reviewing my app.
The reason I can be so sure of that is threefold:
The app does support Android Pie – or rather Android Pie supports it! As it stands the app doesn’t use any features that require this level of the SDK so doesn’t need any special coding. I have a Google Pixel 2 XL, running Android Pie, and it’s been running the app fine for months.
The claim that ‘more then half of the users cannot use the app properly‘ is obviously targeted at people who are not in the mobile development space. Looking an the Android distribution dashboard it is clear the Android Pie is still in it’s infancy – with a distribution of less than 0.1% it doesn’t even make it onto the chart! Not surprising when only a small handful of phones, including the Pixel 2/XL, are actually running it.
Finally, the email says that the app ‘looks great’ – which, I’m afraid to say, it doesn’t! It looks dated and is in need of an overhaul (which is on the cards in the New Year). Maybe the email is just trying to appeal to my ego – but then again I doubt it.
So yet another scam email trying to fleece the unwary of ‘a couple of days’ of development time for some questionable updated along with, undoubtedly, the loss of control of their source code and God only knows what hidden costs.
I obviously didn’t respond but there are plenty of apps out there that have been written for companies with no internal development resource and these are the real targets of this type of scam. I’ve written apps for a number of clients in this situation.
Using the ‘scatter-gun’ approach they are bound to find a few unwary app owners out there who may just be taken in by this. And herein lies the problem – to make this kind of thing worthwhile when the response will be quite low, the returns need to be high from each victim!
Smite is a wooden garden game based on a Northern European game and played around the world.
If you think of a combination of skittles and boules you’ll be pretty much there – but not quite, there are a few twists.
Each player will take turns to throw a wooden ‘smitter’ at 10 numbered wooden pins, arranged in a similar manner to those in 10 pin bowling.
Knock over a single pin and you score the number on that pin.
Knock over two or more pins and you score the number of pins that fall; knock over four pins and you score four points.
Before the next players turn the pins are stood back up but remain where they fell, they are not returned to their original location.
Miss all the pins three turns in a row and you are ‘smitten’ and out of the game.
If any players score exceeds 50 points they are returned to 25..!
When a player scores exactly 50 points the game will end when the round completes – all remaining players will complete the round. There can be more than one winner!
It sounds simple but when the pins start to spread out the game becomes much harder – I can personally attest to this, as can many members of my family..!
Keeping score is not difficult but games can go on longer than expected and you soon find yourself scrabbling around for scraps of paper to continue the scoring.
Having run out of paper on many occasions I decided to create a simple app to keep score and apply the simple rules above. The ability to take player photos to use as avatars and ensuring that game state is saved when the app is backgrounded (lunch and dinner frequently interrupt a ‘a few quick games of Smite’) add some nice functionality and coding challenges.
Written using Xamarin.Forms there are Android and iOS versions of the app with around 95% of the code being shared – only a couple of small platform specific classes were required.
I currently have a few testers looking at the release candidate version – with a few more being recruited at the upcoming Smite World Championships.
It’s a pretty straightforward app and nowhere near as complicated as the likes of my other apps, FillLPG or Motorhome Stopover, but I fully expect to have a few bugs to fix and features to add.
I’m currently writing a Xamarin.Forms scoreboard application which, as part of the functionality, allowed each player to take a photo which would be displayed within their ‘player tile’. I made use of the Xam.Plugin.Media plugin developed by James Montemagno to implement this feature and everything was working like a charm. I then parked the project for a couple of months while I attended to some paying development and training.
When I returned to the project I looked at the outstanding items on my backlog and decided to implement the saving of game state when the app is backgrounded. This was pretty straightforward and I had it nailed in a few hours by adding code to the OnStart, OnSleep and OnResume handlers in the shared class library (in this case, a PCL). After testing the functionality I then ran through a manual ‘smoke test’ to make sure everything was working as expected – and that’s when the trouble started 🙁
I was initially working on the Android version and I quickly discovered that the photo taking functionality appeared to be broken. When I took a photo and then accepted it using the Android camera app I was taken back to a blank player list!
This didn’t used to happen – this was working code and I was certain I hadn’t change anything to do with the player photo code.
I then decided to create a quick and dirty app to pull in just the packages I needed to take a photo and display it within a view – and that worked just fine using the same versions that I had in my project, so the “problem” was in my code.
Returning to my code, the first thing I tried was to update all the Nuget packages. Some time had passed since I’d last opened the project and there were a number of updates pending. I was testing on my Pixel 2 XL running Android P (I’m in the beta program) and maybe, just maybe there was a mismatch here. As it was, this made no difference but it was a good job done – I’d have needed to do this anyway so no time like the present.
PCL v .NET Standard?
One major difference was that my app was using a Portable Class Library (PCL) while the sample app used .NET Standard (as you can’t create a PCL version now). Maybe that was my problem – maybe I needed to upgrade to please the plugin and/or Xamarin.Forms 3.0. Deciding it was another useful exercise anyway I decided to do just that – I created a new shared class library using .NET Standard and pulled my code over (a very simple process considering).
No joy – the problem persisted!
Then, in a moment of clarity, I wondered whether this was a problem was present in the iOS version of the app and to my surprise I found that it wasn’t. Running the smoke test on an iPhone 6s demonstrated the expected behaviour.
Going back to Android and diving into logcat I didn’t find anything obvious in terms of errors but then I saw a debug output message that I had added to the OnResume handler while developing the Save Game functionality. Why was that being called?
Then the penny dropped and it’s a fundamental part of the way that Android works.
When I called into the plugin to take the photo it opened up the Android Camera app – temporarily backgrounding my app in the process. When the user takes and accepts the photo, the Camera app will return control to my app, passing it the image data, and thus bring it into the foreground.
Of course, when the app is backgrounded the OnSleep handler is called and when it is brought into the foreground OnResume is called. In my case the OnSleep handler wasn’t a problem, but the OnResume hander was a different matter.
When resuming the app will now attempt to locate any saved state and if found it will deserialise the data and initialise the state to continue the saved game. But, if no saved state was found it will assume that the app is being opened with no saved state so it would just create a new game – and this is what it was doing, creating a new game with an empty player list!
A quick update to handle this unexpected backgrounding/foregrounding behaviour and I was back to a fully working app on iOS and Android.
The fact that the camera app was temporarily backgrounding my app didn’t dawn on me at the time but when I thought about it it was obvious.
A frustrating few hours to be sure but at the end of the day the app is now working the way it was intended to work and it’s now running with .NET Standard with all Nuget packages updated.
A while ago I eluded to the fact that I was revisiting Xamarin.Forms for cross platform mobile development – previous projects had used the ‘native’ Xamarin.Android and Xamarin.IOS toolkit.
I was interested to see how far Xamarin.Forms had come since my last encounter where I found it lacking in some critical functionality that was required for the project at hand – primarily when dealing with Maps.
When I was approached by a user of my FillLPG application to write something along a very similar line, i.e. a number of points of interest displayed on a map with clickable markers to display more details, for both Android and iOS I wondered whether Xamarin.Forms had matured enough to do the job.
The application is a companion to the Motorhome Stopover website which provides it’s members with access to over 600 locations around the UK where they can park overnight for free. While these are not campsites, facilities vary from location to location, they do provide a useful service when drivers are travelling across the country to their ultimate location (not everyone wants to drive from Edinburgh to Penzance in one day and being able to break the journey is a godsend).
The app requirements were very simple, for the minimum viable product (MVP) anyway.
Authenticated Motorhome Stopover members should be able to view all currently active locations on a map, view contact details of any location and the facilities it provides and, using the device’s built-in navigation capability, navigate a route from the users current location.
Essentially, with the addition of an FAQ and About page, the app boiled down to a map showing stopover locations and a page listing contact and facility details for a location when the user tapped on its marker. If Xamarin.Forms couldn’t deal with this then I was going to be surprised.
The client was an Android user so much of the initial development was undertaken with that in mind and I focused on getting that version to a level where it was functional and he was happy – then I would take a run at the iOS version.
Initial development was undertaken prior to the release of Xamarin.Forms 3.0 but later upgraded without any problems – nothing appeared to be broken and everything just worked.
Looking back at my previous forays into Xamarin.Forms I think that the biggest hurdle was Custom Renderers. The problem being that documentation was very sparse and with the base toolkit not providing the level of customisation I wanted I didn’t have the confidence to plough on and develop Map Renderers only to have to revert to native development.
This time around the documentation was there in abundance, along with GitHub samples and a Xamarin University course. How times have changed 😉
That said, it wasn’t plain sailing and there were still a few speedbumps along the way – although many of these can be attributed to climbing the learning curve of Xamarin.Forms rather than problems with the toolkit itself.
The best thing was, when I turned my attention to the iOS version of the app there was very little to do once the Custom Renderer for the map was completed and wired up. Everything else pretty much worked as expected with the only additional development being that of addressing minor styling and layout differences as can be seen in the screenshots below.
Not withstanding the need for additional features such as searching and filtering there is still some work to do. This mainly centres around testing and everything that facilitates it, e.g. dependency injection in Xamarin.Forms and how to do this within a Unit Test.
The ease with which I was able to develop these applications and the level of code reuse has certainly confirmed to me that Xamarin.Forms is more than just a tool to create very simple applications, quick mock-ups or proof of concept apps.
Overall I’m pretty happy with the initial release of the applications. Yes they are a bit feature-light at the moment and need a bit of polish here and there, but I’ve learned the hard way that at some point you just you need to ship something otherwise it will never see the light of day!
By defining a clear Minimum Viable Product I was able to focus on the core functionality and not get bogged down in the minutiae.
With the most recent update to the FillLPG application (v184.108.40.206) rolling out I will be ceasing all development of this version (unless some horrible bug raises it’s ugly head). But fear not loyal LPG users – that doesn’t mean the the app will be going away – far from it.
Technology moves on at pace and over time new skills are acquired and lessons are learned. The ‘problem’ is that to implement all of this it is easier to start over again – taking advantage of the new framework features, applying the new skills and remembering those sometimes painful lessons.
So, what’s on the horizon?
I suppose the ‘headline’ news is that an iOS version will soon be a reality! After years of focusing solely on the Android version our Apple-using LPG’ers will be getting some love too.
The aim will be to develop an iOS application with feature parity to the current Android version.
Now, don’t fret if you are an Android user – I’m not abandoning all of you who have helped make the app what it is today. The fact that I can essentially develop for two platforms at the same time is due to the advances made in the underlying framework used to develop the app. Previous versions didn’t really lend themselves to the type of mapping that is required for the FillLPG app – but that’s all changed now and mapping is now fairly straightforward to achieve on both platforms whilst sharing the maximum amount of code – which is good for maintainability (fix a bug in one place and it’s fixed for Android and iOS).
With the rest of the application mainly consisting of ‘Forms and Lists’ and these can easily be shared between the new platforms.
The result will be a more modern UI, lower impact on battery life and data usage.
Other planned features include:
Offline price updates (updates will be pushed when your device next has internet access)
“Route Planning” – display stations along a particular route allowing you to plan stops
Enable/Disable update alerts for favorite stations
But there’s more…
The webmaster of the FillLPG website is currently developing a new version with a new and improved webservice – which is how the app communicates with the site. This will expose a lot more data to the app, including:
Flags such as ‘Disabled Friendly’ and ‘SafeFill Capable’
Ability to specify price currency
Obviously I have no control over the timescales for the new website functionality but as soon as it is available I will be including it into the application as quickly as I can.
Please remember though that the FillLPG website and the mobile apps are ‘labours of love’ and that both myself and the site webmaster have other commitments. The website and apps are provided free of charge and with no ads.
I first passed my Xamarin Mobile Certification back in June 2014 but when it came to taking the recertification exam the following year I never quite got around to it. Ultimately it lapsed and I while I was no longer certified I did keep my University subscription running so that I could keep my skills up to date.
During the next year I have to say that I was quite disappointed as there didn’t really seem to be any new content, i.e. no new courses were added as far as I could tell. At the end of that year I was considering not renewing my University subscription, at $1500 it was not exactly a no-brainer.
Then Xamarin was bought by Microsoft and it was included in the MSDN subscription, effectively saving me $2000. With the promise of new content I decided to renew my University subscription – I was $500 up anyway so why not I thought.
Well, as promised, new content is being added, a handful of Azure courses and one on Xamarin.Forms custom renderers so far. That and the fact that I’m currently engaged as a Xamarin developer I thought it would be prudent to refresh my certification. That, coupled with the fact that the Certification and Recertification exams are to change on 15th October this year meant I had a definite timeframe.
Xamarin list 10 courses as being required knowledge for the recertification exam so I spent a couple of weeks reviewing these – making notes and doing the exercises – before embarking on the exam.
The exam itself is 100 multiple choice questions which must be completed within three hours. The pass mark is 80% so not a lot of wiggle room here.
During the exam itself there were a few, shall we say, curve balls – questions which, to me, seemed quite ambiguous. One mentioned an image which was not present resulting in me having to guess the correct answer based on the text – which proved unsuccessful as it turned out – it was in the list of incorrect answers. If I’d missed the 80% by a single mark I don’t think I would have been too happy. As it was I passed with a score of 87% which I’m pretty happy with.
I’ve finally managed to get some time to look at the Smite Scoreboard application that I’m using as a vehicle to dive into Xamarin.Forms (XF) and it’s been a fraught time (see bottom of post).
Between incompatible nuget packages, mismatched Windows and iOS configurations and finding that XF didn’t actually support what I wanted to do I was pretty close to saying, “you know what, to hell with it – I’ll just use the native Xamarin approach instead”.
Anyway – getting back to the Smite Scoreboard app and what is basically the first User Story.
As a user I want to be able to create a list of players, adding, editing and removing as appropriate.
Now, I know what I wanted to do to implement this story – a simple ListView with an ‘Add Player’ button which would open a modal dialog . The dialog would contain a ‘Player Name’ field with OK and Cancel buttons. Entering a name and tapping OK would add a new row to the ListView. Simple huh.
Well no, not really. While XF does support modal pages, which take up the whole screen, it does not support modal dialogs.
I tried a couple of approaches including the creation of a layout with an Entry field above the ListView which would replace the field I was going to put in the dialog. I had this partly implemented but really didn’t like how it was working and decided to bite the bullet and find a way or make a way!
And this is what I came up with (iPhone on the left, Android on the Right):
Yes – it’s not pretty but it shows me that I can do what I want to be able to do. Making it look nice is a job for later, lets get it working first ?
So, on to the code. I decided to address the initial problem – how do I create a modal dialog (or the impression of a modal dialog) which will allow data entry? I didn’t worry about the ListView integration as I’m happy enough that I can make this work.
Basically he uses an AbsoluteLayout which will hold the ‘normal’ page elements as well as a ContentView which will form an overlay that the user can see through but crucially not tap through. The ContentView is initially loaded with it’s IsVisible property set to false.
The skeleton xaml file looks like this:
<AbsoluteLayout><!-- Normal Page Content --><StackLayoutAbsoluteLayout.LayoutBounds="0, 0, 1, 1"AbsoluteLayout.LayoutFlags="All"><!-- Normal Page Content --></StackLayout><ContentViewx:Name="overlay"AbsoluteLayout.LayoutBounds="0, 0, 1, 1"AbsoluteLayout.LayoutFlags="All"IsVisible="False"BackgroundColor="#C0808080"Padding="10, 0"><!-- Overlay --></ContentView></AbsoluteLayout>
With this in place I added a button to the StackLayout and bound the Click event to a handler in the code behind which flipped the IsVisible property of the ContentView to True, thus displaying the overlay.
All I had to do now was to create a layout within the ContentView which looked something like a dialog. I came up with this:
<StackLayoutOrientation="Vertical"BackgroundColor="White"HeightRequest="175"WidthRequest="300"HorizontalOptions="Center"VerticalOptions="Start"Margin="0,20,0,0"><LabelBackgroundColor="Black"FontSize="18"TextColor="White"HorizontalOptions="Fill"Text="Add a Player"/><Entryx:Name="EnteredName"Placeholder="Player Name"TextColor="Black"VerticalOptions="CenterAndExpand"HorizontalOptions="Center"WidthRequest="250"/><StackLayoutOrientation="Horizontal"HorizontalOptions="Center"><ButtonText="Cancel"FontSize="Large"VerticalOptions="CenterAndExpand"HorizontalOptions="Center"Clicked="OnCancelButtonClicked"/><ButtonText="OK"FontSize="Large"VerticalOptions="CenterAndExpand"HorizontalOptions="Center"Clicked="OnOKButtonClicked"/></StackLayout></StackLayout>
Wiring the buttons up to flip the IsVisible property of the overlay back to false and, in the case of the OK button, access the entered value was straightforward enough.
It should be noted that I had issues when I attempted to update to the latest version of Xamarin.Forms via Nuget. The version installed with the ‘File > New Project’ did not seem to like the Overlay configuration and while the semi-transparent background was visible the ‘dialog’ controls were not. Only by updating from 220.127.116.1182 (installed by default) to 18.104.22.168 (latest at time of writing) was I able to get this working. But it was not that simple (of course). Version 22.214.171.124 has dependencies on specific version of the Xamarin.Android.Support packages, 23.3.0, but I’d already updated those packages to their latest versions (126.96.36.199). This meant that I had to revert those updates and install 23.3.0 instead.