Extend Label in Xamarin.Forms with a font color property

The label control in Xamarin.Forms does not have a FontColor property. But the control is easy to extend.

First create a new class that inherits from Label.
Create a FontColor property of type string. The value of the FontColor will in this example be an RGBA string.

public class CustomLabel : Label
    {
 
         public static readonly BindableProperty FontColorProperty = 
             BindableProperty.Create<CustomLabel, string>( 
                 p => p.FontColor, ""); 
 
 
         public string FontColor
         { 
             get 
             { 
                 return (string)GetValue(FontColorProperty); 
             } 
             set 
             { 
                 SetValue(FontColorProperty, value); 
             } 
         } 
 
    }

Next step is to write a custom renderer for each platform.

iOS

[assembly: ExportRenderer(typeof(CustomLabel), typeof(CustomLabelRenderer))]
namespace MyApp.iOS.Renderers
{
    public class CustomLabelRenderer : LabelRenderer
    {
 
        protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
 
            if(e.PropertyName == "FontColor")
            {
                var view = (CustomLabel)Element;
 
                var values = view.FontColor.Split(',');
 
                Control.TextColor = UIColor.FromRGBA(int.Parse(values[0]), int.Parse(values[1]), int.Parse(values[2]), int.Parse(values[3]));
            }
        }
    }
}

Android

[assembly: ExportRenderer(typeof(CustomLabel), typeof(CustomLabelRenderer))]
namespace MyApp.Android.Renderers
{
    public class CustomLabelRenderer : LabelRenderer
    {
 
        protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
 
            if(e.PropertyName == "FontColor")
            {
                var view = (CustomLabel)Element;
 
                var values = view.FontColor.Split(',');
 
                var color = Color.Argb(int.Parse(values[3]),int.Parse(values[0]), int.Parse(values[1]), int.Parse(values[2]));
 
                Control.SetTextColor(color);            
            }
        }
    }
}

Windows Phone

[assembly: ExportRenderer(typeof(CustomLabel), typeof(CustomLabelRenderer))]
namespace MyApp.WinPhone.Renderers
{
    public class CustomLabelRenderer : LabelRenderer
    {
 
        protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
 
            if(e.PropertyName == "FontColor")
            {
                var view = (CustomLabel)Element;
 
                var values = view.FontColor.Split(',');
                Control.Foreground = new SolidColorBrush(System.Windows.Media.Color.FromArgb(byte.Parse(values[0]), byte.Parse(values[1]), byte.Parse(values[2]), byte.Parse(values[3])));
            }
        }
    }
}

To use the custom label in XAML you need to declare the namespace.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
					   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
					   x:Class="MyApp.Views.MyView"
            xmlns:controls="clr-namespace:MyApp.CustomControls;assembly=MyApp">

Then you can use the control i XAML like this:

<controls:CustomLabel FontColor="255,255,255,255" Text="My custom label" />

Handle Windows Phone back button pressed when using MVVM

When I building an app with a MVVM framework I want to have my view models in a portable class library so I can use same view models for the Windows Phone app as for the iOS and Android app when building apps using Xamarin.

If I press the back button in a Windows Phone app built using MvvmCross (a MVVM framework), the app will be placed in background. That is the behavior I want if I'm on the first view of the app. But if I have navigated to Another view I would like to return to the previous view. To do that I need to handle the back button event. I want to have the code for handle the back button event in my view models that is placed in a portable class library, but the code for handling the event is platform specific. This post will show how to handle the back button event in a Windows Phone app built using WinRT. You can of course use this way to handle platform specific events for other events than the back button event.

First of all I creating an interface, I use to name it IPlatformEvents.

public interface IPlatofrmEvents
{
     event EventHandler BackButtonPressed;
}

In my view models I using IoC (Inversion of Control) and constructor injection to resolve the interface. In my method for handling the back button pressed I using the Close method to close the current view and return to the previous one in the stack. Don't forget to remove the handler from the event in the handler method. If you do not, it can cause problems later.

public class MyViewModel : MvxViewModel
{
     private IPlatformEvents _platformEvents;     
 
     public MyViewModel(IPlatformEvents platformEvents)
     {
          _platformEvents = platformEvents;
 
          _platformEvents.BackButtonPressed += BackButtonPressed;
     }
 
     void BackButtonPressed(object sender, EventArgs e)
     {
         Close(this);
         _platformEvents.BackButtonPressed -= BackButtonPressed;
     }
}

If you want to read more about IoC and MvvmCross you can read my post about MvvmCross and IoC and my post about how to use a different IoC provider then the built-in when using MvvmCross.

Next step is to write the platform specific implementation of the interface. For an Windows Phone app using WinRT the implementation would look like this.

public class WindowsPhoneEvents : IPlatformEvents
{
      public event EventHandler BackButtonPressed;
 
      public WindowsPhoneEvents()
      {
          HardwareButtons.BackPressed += HardwareButtons_BackPressed;
      }
 
      void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e) 
      { 
             if(BackButtonPressed != null) 
             { 
                   BackButtonPressed(this, new EventArgs()); 
                   e.Handled = true; 
             } 
      } 
 
}

When I have created the platform specific implementation I just have to register it to the IoC container. You can read how to do it if you read the post that I linked to above.

Building a tabbed app using Xamarin.Forms

Xamarin.Forms is one of the biggest news with Xamarin 3. With Xamarin.Forms you can build UI for 3 platforms (Windows Phone, iOS and Android) with one shared codebase. What is unique for Xamarin.Forms is that the UI code you are writing with Xamarin.Forms will render native UI controls. That means that the UI will look like a Windows Phone app when running the code on a Windows Phone and it will look like a iPhone app when running the code on an iPhone and the same on Android.

Create a Xamarin.Forms project in Visual Studio
This post will show you the basics when building an app with Xamarin.Forms in Visual Studio 2013. You can also build apps using Xamarin.Forms with Xamarin Studio but for the Windows Phone project you need to use Visual Studio.

To create an app with Xamarin.Forms open the new project dialog. Xamarin.Forms project templates is located under "Mobile Apps". There are three types of project you can create, a blank app with the code in a project of type portable class library (the project will be referenced in each client project), a blank app with shared code (you have to link the each file to each client project) and a class library of type portable class library.

In this tutorial I will use the first choice because I want Visual Studio to create the client projects (projects for Windows Phone, iOS and Android) and I think it's easier to reference an assembly than linking files.

Create dialog

Now Visual Studio has created four projects, the client projects and a project for the shared UI code.

In the shared project I add a new item based on the template called "Forms Xaml Page". Then a XAML-file and a code behind file is created.

Many of the tutorials I have read writes the most of the code in the code behind file, but I want to use XAML as much as possible. One disadvantage to use Visual Studio is that there is not intellisense for the XAML-code. If you miss it to much you can use Xamarin Studio instead.

Create an app with tabs

The app in this tutorial will be a app with two tabs/views and for that we will use a tabbed page. This post will just use standard styles. But you can both style the app for all platforms or you can do platform specific styling.

In the view we just created ad the code below. This will be a container for the views in the app.

<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
					   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
					   x:Class="FormsDemo.FirstView"
            Title="News">
 
</TabbedPage>

You also need to go to the code behind file and make the class inherit from "TabbedPage".

Next step is to create the content views, this app will have one for news and one for settings, so I add two new forms xaml pages to the shared project. Before I starting to create each view I will add them to the tabbed page. This is done from the code behind file of our "container".

public partial class FirstView : TabbedPage
    {
        public FirstView()
        {
            InitializeComponent();
 
            Children.Add(new NewsView());
            Children.Add(new SettingsView());
 
        }
    }

The title for the tabs will be the title we set as Title property on ContentPage for each view.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
					   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
					   x:Class="FormsDemo.NewsView" Title="News">

Add a list to the app
My first tab will be a list with news. For that I using the ListView control that is included in Xamarin.Forms.

<ListView x:Name="News" ItemsSource="{Binding News}" RowHeight="80" BackgroundColor="Transparent">
    <ListView.ItemTemplate>
      <DataTemplate>
        <ViewCell>
          <ViewCell.View>
            <StackLayout Orientation="Vertical" Spacing="0" Padding="10">
              <Label Font="Bold,20" Text="{Binding Header}" />
              <Label Font="16" Text="{Binding Text}" />
            </StackLayout>
          </ViewCell.View>
        </ViewCell>
      </DataTemplate>
    </ListView.ItemTemplate>
  </ListView>

And the code behind will look like this:

public partial class NewsView
    {
        public NewsView()
        {
            InitializeComponent();
 
            BindingContext = new NewsViewModel();
        }
    }
 
    public class NewsViewModel
    {
        public NewsViewModel()
        {
            News = new List<NewsItem>()
            {
                new NewsItem()
                {
                    Header = "Header 1",
                    Text = "Text 1"
                },
                new NewsItem()
                {
                    Header = "Header 2",
                    Text = "Text 2"
                }
            };
        }
 
        public List<NewsItem> News { get; set; }
    }
 
    public class NewsItem
    {
        public string Header { get; set; }
        public string Text { get; set; }
    }

iPhone

Windows Phone

Android

On the settings page I using the Switch control to turn news sources on or off.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
					   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
					   x:Class="FormsDemo.SettingsView">
  <StackLayout Orientation="Vertical" Padding="10">
	  <Label Font="Bold,20" Text="News sources" />
    <StackLayout Orientation="Horizontal">
      <Label Text="Xamarin" VerticalOptions="Center" />
      <Switch VerticalOptions="Center" />
    </StackLayout>
    <StackLayout Orientation="Horizontal">
      <Label Text="Microsoft" VerticalOptions="Center" />
      <Switch VerticalOptions="Center" />
    </StackLayout>
  </StackLayout>
</ContentPage>

Windows Phone

Android

iPhone


That was the basics to build an tabbed app with Xamarin.Forms. Of course you can do much more than this with Xamarin.Forms.

TechDays 2014

Den 19-20 november (17-20 november med pre-conf inkluderat) anordnas utvecklarkonferensen TechDays av Microsoft. Jag och min Sogeti- och IO2GameLabs kollega Johan Karlsson har fått äran att vara med på den. Vi kommer att prata om det vi brinner mest för nämligen cross platform utveckling för mobila enheter.

På pre-conf (den 17 november) kommer vi tillsammans med Peter Bryntesson (Microsoft), Johan Lindfors (Coderox) och Anderas Hammar (Jayway) att hålla en heldag om hur man bygger appar för Windows (Windows Store och Windows Phone) och för iOS och Android med Xamarin. Läs mer här.

Under själva huvudkonferensen kommer jag och Johan att ägna ca en timme till att berätta hur vi har arbetat med vårt spel WordRoom för att göra det cross platform med Xamarin och Microsoft Azure. Läs mer här.

Tycker ni att detta låter intressant tycker jag ni ska komma till TechDays på Kistamässan, självklart kommer det bjudas på massa andra intressanta föreläsningar också. Se hela programmet här.

Running Windows Phone emulator in Parallels on OS X

If you're developing apps for all the major mobile platforms i guess you are using a Mac since that is the only way you can build iOS apps. If you're using Parallels to run Windows for Windows Phone development you need to activate nested virtualization if you want to use the emulator. This is because that Windows Phone emulator is using virtualization with Hyper-V.

To activate nested virtualization, shut down your virtual machine if it is started. Then open the configuration view for your machine in parallels and go to the "Optimization tab" and check "Enable nested virtualization". When you start your virtual machine you'll be able to use Hyper-V and the Windows Phone emulator.

Configuration dialog for virtual machine

Authentication for REST calls with HTTPClient to Azure MobileServies

In a current project I working with an app that uses a .NET Backend in Azure Mobile Services. Backend is a WebAPI.

On client side I have all the code for networking in portable class library so I can reuse it on other platforms. Right now we are building the app for Windows Phone, but the plan is to build it for both iOS and Android using Xamarin. I am using the HttpClient object to do the REST calls. HttpClient is not in portable class library per default. But if you download “Microsoft HTTP Client Libraries” from NuGet you will get it.

My first problem was about which credentials I should use for the REST call to Azure. You can only see the application key in the portal. Is that the password? And what is the username in that case? The answer is that the application key is the password and username is just an empty string.
Problem number two was how to specify the credentials. My first try was to add the as the code below shows.

var handler = new HttpClientHandler {Credentials = new NetworkCredential("", "appKey") };
 
var client = new HttpClient(handler);

But then I got a 401 (Unauthorized) error back. After some mail conversations with the always helpful Mobile Services team we consider that the problem probably was that the call does not try to authenticate with basic authentication. When I tried the code below instead of the code above it worked.

var client = new HttpClient();
                client.DefaultRequestHeaders.Authorization = 
                    new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes(String.Format("{0}:{1}", "", "appKey"))));

Build 2014

Now we are in San Francisco for the BUILD Conference that starts on Wednesday. It was a long flight from Sweden yesterday, but I used the time for coding. Have to say that Surface Pro is an excellent device for coding on an airplane.

What I expect from the BUILD conference is a big amount of inspiration from great lectures and people, new knowledge about developing for the Microsoft platform and some product news specifically for Windows Phone.

The most discussions before has been about Windows Phone 8.1 but I have also read some that speculating about a preview of Windows 9.

I saw the schedule for the first time earlier this morning and it will not be easy to select what to listen on.

If you want to follow us on Build you can do it here on my blog and on Twitter, my username is @hindrikes and Johan's is @johankson.

Workaround for invalid markup problems when developing for Windows Phone

Every time I open up a Windows Phone Project in Visual Studio 2013 I got a lots of  errors in the XAML markup. The designer shows "Invalid markup" and the error list is long. I found a workaround for this:

  1. Open Configuration Manager for your Visual Studio solution
  2. Change platform for the Windows Phone Project to x86
  3. Build the Project and the errors is gone
  4. Open Configuration Manager again and change back to "Any CPU"

After follow above steps it will work until you start Visual Studio again.

Windows Azure Mobile Services in Portable Class Library

In my current project, a multiplayer game for mobile devices I only using Windows Azure Mobile Services as backend. The game will be available for multiple platforms and I will use Xamarin for iOS and android.

When using Xamarin I can reuse a lot of code if I using PCL (Portal Class Library) that i shipped with Visual Studio. When creating a new PCL-project you can choose which taget platforms the project will build for, in my case Windows Phone, Windows Store, Xamarin iOS and Xamarin Android.

In order to reuse so much code as possible I want to have the communication with my backend in PCL. When using Windows Azure Mobile Services I can have all communication there except for the code for authentication. But then I put an interface i PCL and each platform will have a specific implementation of the interface.

But where to find the Mobile Services assemblies for PCL? I installed Mobile Services via NUGET to my Windows Phone project (Windows Phone is my first platform). But Mobile Services was not just installed to my Windows Phone project, I also got the assemblies for PCL (and other platforms) i my packages folder. It enabled me to add the assemblies manually to the PCL-project.

Glyphicons on Windows Phone

If you using Twitter Bootstrap and glyphicons and having problem that the glyphicons is not showing up on Windows Phone you need to add the MIME-type to your web.config.

<System.webServer>
    <staticContent>
       <mimeMap fileExtension=".woff" mimeType="font/x-woff" />
    </staticContent>
</system.webServer>