Wednesday, May 17, 2017

Problems with Xamarin

Xamarin.Forms uses XAML in similar ways to WPF. But in Visual Studio 2017 it has many problems. The worst of these is the inability of the editor, compiler, builder, or even the run-time to report errors in XAML. When you make XAML errors the InitializeComponents call never returns and you get a blank screen. Here are a few simple errors that will give you the dreaded blank-screen of nausea.

Let's start with something that works - here is the MainPage.xaml from the default Xamarin.Forms PCL project template.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:Broken"
             x:Class="Broken.MainPage">

<Label Text="Welcome to Xamarin Forms!" 
           VerticalOptions="Center" 
           HorizontalOptions="Center" />

</ContentPage>

Which looks like this on the emulator.


Now let's make a mistake and reference a non-existent style.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:Broken"
             x:Class="Broken.MainPage">

<Label Text="Welcome to Xamarin Forms!" 
           VerticalOptions="Center" 
           HorizontalOptions="Center"
           Style="{StaticResource MyStyle}"/>

</ContentPage>

Now we get a blank screen. If you put a breakpoint on InitializeComponent() and then single-step you will see it never returns.

Let's add the style but get the case wrong on the key (like we've never done that!)

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:Broken"
             x:Class="Broken.MainPage">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style x:Key="myStyle" TargetType="Label">
                <Setter Property="Background" Value="Red"></Setter>
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>
<Label Text="Welcome to Xamarin Forms!" 
           VerticalOptions="Center" 
           HorizontalOptions="Center"
           Style="{StaticResource MyStyle}"/>

</ContentPage>

We get the same blank page. In fact you get a blank page if you forget the TargetType parameter, if you don't specify any <SETTER>s, you get the property name wrong, you get the value wrong, or pretty much any other error you think of. Add to this the fact that everything is case-sensitive and there is almost no intellisense and you can see that developing Xamarin.Forms in Visual Studio 2017 is bloody frustrating.

Update: There is a solution to this but it is non-intuitive. There is an exception being thrown but it is being thrown away by Xamarin Forms. You simply have to catch the exception and rethrow it like this.

        public MainPage()
        {
            try
            {
                InitializeComponent();
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

Then you get a useful error message popping up.


No comments:

Post a Comment