Nick's .NET Travels

Continually looking for the yellow brick road so I can catch me a wizard....

Visual States in Xamarin.Forms using BuildIt.Forms

A couple of weeks ago I started building out some helpers to make working with Xamarin.Forms a little nicer (see Styling Pages and Controls in Xamarin Forms using Visual States,Rebuilding the Xamarin.Forms Button with Visual States and Control Templates and Ambient Properties in Xamarin.Forms). Since then we’ve been working on building out a library that encapsulates these features, again making it easier for us and others to build apps using Xamarin.Forms. There is now a pre-release version of BuildIt.Forms ( that anyone can reference to take advantage of these helpers. The library makes use of some methods/properties that are only available in the pre-release version of Xamarin.Forms, which is why we don’t have an actual release out yet.

In this post I’m going to walk through using visual states in a Xamarin.Forms project. To set the scene, I’m going to step through creating a new Xamarin.Forms project in Visual Studio 2017 (current RTM build, not the preview, although the preview build should be similar). I’ll do this in this post to make sure the basics of creating a Xamarin.Forms project that uses a .NET Standard Library instead of a PCL library is covered. I highly recommend switching to a .NET Standard library as soon as possible to avoid issues with upgrading nuget references etc (most third party library now have a .NET Standard version and it will become increasingly harder to maintain and update your old PCL libraries).

Ok, so let’s get started with a new project – I’m going with the Cross Platform App (Xamarin) template in the New Projects dialog:


Next, I’ll select the Blank App template, using Xamarin.Forms (UI Technology) and Portable Class Library (Code Sharing Strategy). Side note here – I highly recommend not using the Shared Project option for Code Sharing Strategy; using this option is a recipe for disaster as it promote poorly separated UI logic and allows for using conditional compilation based on #defines which is not a good strategy if you want maintainable code.


After clicking OK my solution has four projects: A PCL which has got the Xamarin.Forms UI defined in XAML files, and three “head” projects, one for each target platform. At this point, I would suggest running each project to make sure you have a working application before going any further (and commit this code to your source repository before going any further!)


Now to replace the PCL with a .NET Standard library. I’ll add a new .NET Standard class library. I like to make it clear that this library will contain the UI for my Xamarin.Forms project by using the .UI suffix. I do not include my view models in this library – I’ll talk about this in a subsequent post.


After creating the new class library, I just need to copy across the XAML and .cs files that were in the PCL library (App.xaml, App.xaml.cs, MainPage.xaml, MainPage.xaml.cs).  I can then remove the PCL library from the solution. Of course, I need to go through each of the head projects and add a reference to the UI project.


At this point I would again build and run the application on each platform – If you do this without doing anything the solution won’t compile as the UI library doesn’t have a reference to the Xamarin.Forms NuGet library. I suggest adding a reference to the Xamarin.Forms NuGet library and then upgrading any libraries where there is an update available. Again before proceeding, build and run each platform.

The next step is to add a reference to BuildIt.Forms. This is a prerelease library so you’ll need to check the “Include prerelease” option when searching. You need to add this library to all projects, even though you’ll only be adding code into the UI project – this makes sure the platform specific libraries that are included in BuildIt.Forms are correctly referenced and will be included.


As part of referencing BuildIt.Forms you will notice that the reference to Xamarin.Forms has also been updated to the prerelease version – as BuildIt.Forms takes advantage of some prerelease APIs this is unavoidable at the moment. The official release of BuildIt.Forms will not be available until the next drop of Xamarin.Forms where these APIs come out of prerelease.

Now we can start to make use of some of the helpers in BuildIt.Forms. In this case we’re going to use visual states in the XAML for the MainPage to hide and show a Label. The following XAML includes a Label and two Button elements. There are two visual states defined: Show and Hide (the actual names are only relevant when switching visual states, they have no bearing on what the visual states do). Note that the Show visual state doesn’t need to explicitly set the IsVisible property on the WelcomeText Label to true, since this is the default value for that property.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns=""
         <x:Array Type="{x:Type vsm:VisualStateGroup}">
             <vsm:VisualStateGroup Name="SampleStates">
                <vsm:VisualState Name="Show" />
                 <vsm:VisualState Name="Hide">
                         <vsm:Setter Value="false"
                                     Target="WelcomeText.IsVisible" />

     <StackLayout VerticalOptions="Center"
         <Label x:Name="WelcomeText"
                Text="Welcome to Xamarin Forms!" />
         <StackLayout Orientation="Horizontal">
             <Button Text="Show"
                     Clicked="ShowClicked" />
             <Button Text="Hide"
                     Clicked="HideClicked" />

The code for the event handlers for the two button is relatively simple:

public void ShowClicked(object sender, EventArgs e)
     VisualStateManager.GoToState(this, "Show");
public void HideClicked(object sender, EventArgs e)
     VisualStateManager.GoToState(this, "Hide");


And the final result is an interface that shows and hides the welcome text on the page:


Feel free to try out the BuildIt.Forms library and get started using visual states within your Xamarin.Forms project.

Comments are closed