How to succeed with Xamarin.Forms

Xamarin.Forms makes it possible to write UI for all the major mobile platforms, iOS, Android and Windows Phone with one shared code base. Many developers think that Xamarin.Forms isn’t is good enough to create apps that will be published and they think Xamarin.Forms is more a tool for prototyping.

If you think Xamarin.Forms is a “magic” product that will fix everything, you will properly not succeed with Xamarin.Forms. For me Xamarin.Forms is a framework that helps me build apps for multiple platforms. If you look at Xamarin.Forms in that way you will increase your chances to success with Xamarin.Forms.

Xamarin.Forms is delivered with a lot of controls that uses the Xamarin.Forms framework to render native platform specific controls. A Xamarin.Forms control is in many way just a description of what the control can do. From that description is native controls rendered.

The power of Xamarin.Forms is that you can use the framework to create you own renderers if you want to renderer a control different then the standard renderer. You can also create your own controls by using custom renderers.

I guess one of the most common issues with Xamarin.Forms i ListView performance. It’s not surprising, you maybe have 5 or 6 controls for each cell (row). If cells are reused you might have 8 cells. It means that forms need to create at least 40 renderer objects. And if any of the controls is a StackLayout or a RelativeLayout where it’s render has do to a lot of calculations where to place controls I guess you will realize that it will use a lot of memory.

So if you instead create your own custom cell that has it own renderer, there will be only one renderer for each row or if you write a renderer for the whole list you will only have one renderer. Can you realize how much memory you will save on that? If not you will see it when you are scrolling in your ListView,

The biggest problem when using Xamarin.Forms is that the developers don’t know how Xamarin.Forms works and they don’t know much about the target platforms. If you want to create a excellent app with Xamarin.Forms you still need to have knowledge about the target platforms.

Now you maybe want to ask me why you should use Xamarin.Forms? The answer is that even if you have to write platform specific code for some views there are still much you can use of the controls that is delivered with Xamarin.Forms out of the box and the powerful Xamarin.Forms framework makes it possible to write platform specific code when what you get out of the box with Xamarin.Forms not is enough.

My recommendation is to so do as much as possible with what you get out of the box with forms and don’t care about performance and if it doesn’t look perfect from the beginning. When you have created your app and built all the business logic, then you can start to look at how to make the app perfect. Than you can start write platform specific code to get better performance and a better look of the app.

TechDays 2015

Den 20 oktober börjar TechDays med förkonferens, jag och Johan Karlsson kommer att dela med oss av våra kunskapar gällande cross-platformutveckling.

Att bygga cross-platformlösningar är alltid en stor utmaning då det i grunden är olika operativsystem, programmeringsspråk och utvecklingsmiljöer.
Xamarin löser en stor del av cross platform problematiken genom att man kan utveckla appar för iOS, OSX och Android med C#. iOS och Android kan även byggas i Visual Studio. Under dagen kommer vi gå genom hur man bygger arkitektur och gränssnitt för en optimal native upplevelse på varje plattform, det vill säga iOS, OSX, Android och Windows. Vi kommer också att visa hur man kan testa mobila applikationer på ett effektivt sätt med hjälp av Xamarin TestCloud.

Läse mer här, http://tdswe.kistamassan.se/Program-2015/Sessioner/Pre-Conf-Cross-Platform-pa-ratt-satt

Get started with Xamarin.Forms for Windows

Xamarin has finally released support for Windows apps using WinRT. This make it possible to write apps for Windows Phone 8.1 (the stable release uses Windows Phone 8 Silverlight but can be upgraded to Windows Phone 8.1 Silverlight by changing target platform) and Windows 8.1. It’s still in preview and Xamarin not recommending that we uses it for production apps yet. This post will show you how to add Windows apps to your existing Xamarin.Forms project.

First thing to do is to make sure that you have the correct PCL profile for your shared Xamarin.Forms project. If you have created your project from Xamarin.Forms PCL template you have to check Windows Phone 8.1.

PCL Target type

Next step is to create a Blank Windows App.

Create black Windows app

When you have done that you have to add the nuget package for Xamarin.Forms to the Windows project.

Run Install-Package Xamarin.Forms.Windows -Pre in the “Package Manager Console”.

When the package is installed open up MainPage.xaml and add the Xamarin.Forms namespace and change Page to forms:WindowsPage.

<forms:WindowsPage
    x:Class="MyApp.WinStore.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MyApp.WinStore"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:forms="using:Xamarin.Forms.Platform.WinRT"
    mc:Ignorable="d">
 
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
 
    </Grid>
</forms:WindowsPage>

You also have to remove that MainPage is inherits from Page in MainPage.xaml.cs. To start the forms application run LoadApplication with the App class from the shared project as an argument.

 public sealed partial class MainPage
    {
        public MainPage()
        {
            this.InitializeComponent();
 
            LoadApplication(new MyApp.App());
        }
    }

The last step is to call the Xamarin.Forms Init method (Xamarin.Forms.Forms.Init(e);) in App.xaml.cs. The call should be in the OnLaunched method after before if (e.PreviousExecutionState == ApplicationExecutionState.Terminated). It will be around line 65.

if (rootFrame == null)
            {
                // Create a Frame to act as the navigation context and navigate to the first page
                rootFrame = new Frame();
                // Set the default language
                rootFrame.Language = Windows.Globalization.ApplicationLanguages.Languages[0];
 
                rootFrame.NavigationFailed += OnNavigationFailed;
 
                Xamarin.Forms.Forms.Init(e);
 
                if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
                {
                    //TODO: Load state from previously suspended application
                }
 
                // Place the frame in the current Window
                Window.Current.Content = rootFrame;

Xamarin Forms for WinRT

If you want to use Xamarin.Forms for a Windows Phone 8.1 (with WinRT) app follow the same steps, for a Windows Phone 8.1 project.

Xamarin.Forms: Placeholder text color password box Windows Phone

When using the Entry control in Xamarin.Forms with IsPassword set to true the text color property will not affect placeholder text on Windows Phone. To solve this you need to create a custom renderer for entry in your Windows Phone project.

The native control will be a Grid that contains a PasswordBox (PhoneTextBox if IsPassword is false). The easiest way to find the PasswordBox is to loop through all controls in the Grid and set Foreground color to the text color specified on the Xamarin.Forms control.

[assembly: ExportRenderer(typeof(Entry), typeof(ImprovedEntryRenderer))]
namespace MyApp.WinPhone.Renderers
{
      public class ImprovedEntryViewRenderer : EntryRenderer
      {
            protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
            {
                 base.OnElementPropertyChanged(sender, e);
 
                 if(e.PropertyName == "Renderer" || e.PropertyName == "TextColor")
                 {
                      foreach(var ctrl in Control)
                      {
                           var control = (System.Windows.Controls.Control)ctrl;
                           control.Foreground = new SolidColorBrush(System.Windows.Media.Color.FromArgb(byte.Parse(TextColor.A), byte.Parse(TextColor.R), byte.Parse(TextColor.G), byte.Parse(TextColor.B)));
                      }
                 }
            }
      }
}

You have to run the code both if e.PropertyName is “Renderer” and if it’s “TextColor”. That’s because first time the control is rendered it will use “Renderer” as property name, if text color then is changes it will be used as property name.

You have to set the foreground in OnElementPropertyChanged, if you set it in OnElementChanged it will be changed by the base class. If you set it in OnElementPropertyChanged after you have called the base method it will be the last that is running in the renderer.

Building a ScreenshotManager to capture the screen with code

This blog post will show you how to build a screenshot manager to use from shared code when building apps with Xamarin for Windows Phone, Android and iOS.

First of all we need to create an interface in the shared code library. In this example there will be one method in the screenshot manager. This method will capture the screen and return a byte array that you for example can save to a server.

 public interface IScreenshotManager
 {
        Task<byte[]> CaptureAsync();
 }

All platforms that we will target capture the screen in different ways. Therefor will each platform have a own implementation of the interface. If you register the interface with a platform specific implementation for each platform you can call the ScreenshotManager from shared code.

Windows Phone
For Windows Phone you need to render the root frame into a WritableBitmap.

public class ScreenshotManager : IScreenshotManager
    {
        public async Task<byte[]> CaptureAsync()
        {
            var rootFrame = Application.Current.RootVisual as PhoneApplicationFrame;
 
            var screenImage = new WriteableBitmap((int)rootFrame.ActualWidth, (int)rootFrame.ActualHeight);
            screenImage.Render(rootFrame, new MatrixTransform());
            screenImage.Invalidate();
 
            using (var stream = new MemoryStream())
            {
                screenImage.SaveJpeg(stream, screenImage.PixelWidth, screenImage.PixelHeight, 0, 100);
                var bytes = stream.ToArray();
                return bytes;
            }
        }
    }

iOS
For iOS you need the view from the RootViewController to create a screenshot from. This code will work for iOS7 and above.

public class ScreenshotManager : IScreenshotManager
    {
        public async System.Threading.Tasks.Task<byte[]> CaptureAsync()
        {
            var view = UIApplication.SharedApplication.KeyWindow.RootViewController.View;
 
            UIGraphics.BeginImageContext(view.Frame.Size);
            view.DrawViewHierarchy(view.Frame, true);
            var image = UIGraphics.GetImageFromCurrentImageContext();
            UIGraphics.EndImageContext();
 
            using(var imageData = image.AsPNG())
            {
                var bytes = new byte[imageData.Length];
                System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, bytes, 0, Convert.ToInt32(imageData.Length));
                return bytes;
            }
 
        }
    }

Android
To create a screenshot in Android you need to have access to a activity. The easiest way to access a activity is to create a static method on the ScreenshotManager that you setting before using the ScreenshotManager.

public class ScreenshotManager : IScreenshotManager
    {
        public static Activity Activity { get; set; }
 
        public async System.Threading.Tasks.Task<byte[]> CaptureAsync()
        {
            if(Activity == null)
            {
                throw new Exception("You have to set ScreenshotManager.Activity in your Android project");
            }
 
            var view = Activity.Window.DecorView;
            view.DrawingCacheEnabled = true;
 
            Bitmap bitmap = view.GetDrawingCache(true);
 
            byte[] bitmapData;
 
            using (var stream = new MemoryStream())
            {
                bitmap.Compress(Bitmap.CompressFormat.Png, 0, stream);
                bitmapData = stream.ToArray();
            }
 
            return bitmapData;
        }
    }

Using Context Actions in Xamarin.Forms ListView

One of the news in Xamarin.Forms 1.3 is what Xamarin call context actions. With context actions you can make a ListView much more richer. What you can do is to add a menu to every row in the ListView. On Windows Phone and Android is the menu showing when you’re long pressing on a item, on iOS you will swipe left on the item to show the menu. As you can see on the screenshots below the menu looks different on each platform. On Windows Phone the menu will pop up, on iOS it will be be on the row and on Android at the top of the screen.

contextactions contextactions_android contextactions_ios

To use context action add them to the ViewCell in the ItemTemplate as shown in the code below.

 <ViewCell.ContextActions>
       <MenuItem Text="Share" />
       <MenuItem Text="Buy" Command="{Binding AddToBasket}" />
</ViewCell.ContextActions>

MenuItem has four properties that is good to know:
Text: What’s shown to the user
Clicked: Adds a event listener to the menu item.
Command: Bind a command to the menu item.
IsDestructive: Will make the menu item red on iOS if it’s set to true.

 <ListView ItemsSource="{Binding Products}" VerticalOptions="Start" RowHeight="40">
 
      <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell>
            <ViewCell.ContextActions>
              <MenuItem Text="Share" />
              <MenuItem Text="Buy" Command="{Binding AddToBasket}" />
            </ViewCell.ContextActions>
 
            <ContentView Padding="0,10">
              <Grid>
                <Grid.ColumnDefinitions>
                  <ColumnDefinition Width="2*" />
                  <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
 
              <Label Text="{Binding Product.Name}" TextColor="Black" />
              <Label Grid.Column="1" HorizontalOptions="End" Text="{Binding Product.Price, StringFormat='{0:0.00} kr'}" TextColor="Red" />
 
              </Grid>
            </ContentView>
          </ViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>

Grouping a ListView – Xamarin.Forms

In many cases when you want a list of items you want to group them in the list. To use groups in a ListView with Xamarin.Forms is very easy.

Below are screenshots from Android, iOS and Windows Phone where there is no HeaderTemplate used.
android_groups ios_groups wp_groups

First step is to create a group class that inherits from ObservableCollection and create two properties, one for title and one for short title.

public class ListViewModel
{
     ObservableCollection<MyListViewGroup> Groups {get; set;}
}
 
public class MyListViewGroup : ObservableCollection<MyListViewItem>
{
     public string Title {get; set;}
     public string ShortTitle {get; set;}
}
 
public class MyListViewItem
{
     public string Name {get; set;}
}

IsGroupingEnabled is the keyword to enable grouping for the ListView, if it’s value is true the ListView will be grouped.

GroupTitle is the group title.

GroupShortTitle is the value that will be shown when you tap a group title in Windows Phone and the value at the left side on iOS. Android will not use GroupShortTitle. It will be used to jump a specific group.

To style the header use the GroupHeaderTemplate property.

 <ListView Grid.Row="1" ItemsSource="{Binding Groups}" 
           GroupShortNameBinding="{Binding ShortTitle}" IsGroupingEnabled="true" 
           GroupDisplayBinding="{ Binding Title }">
            <ListView.GroupHeaderTemplate>
              <DataTemplate>
                <ViewCell>
                  <ViewCell.View>
                    <Label Text="{Binding Title}" />
                  </ViewCell.View>
                </ViewCell>
              </DataTemplate>
            </ListView.GroupHeaderTemplate>
            <ListView.ItemTemplate>
              <DataTemplate>
                   <TextCell Text="{Binding Name}" />
              </DataTemplate>
            </ListView.ItemTemplate>
</ListView>

Monitor an app with Xamarin Insights

I Think it’s really important to monitor apps. Of course the most important part is to log errors in the app. But I also like to track how my users uses my apps. For the lastest app I have built I have used a monitoring tool from Xamarin called Insights, http://xamarin.com/insights.

While I alwas have crossplatform and testability in mind when I buildning apps I first create a logger interface.

public interface ILogger
{
     Task InitializeAsync();
 
    //Log exceptions
     void LogException(Exception ex);
 
     //Log information about events, for example view navigation
     Task TrackAsync(string identifier, Dictionary<string, string> details = null);
 
     //Log information about a user
     Task Identify(string userId, Dictionary<string, string> details = null);
}

While Xamarin Insights is compatible with Portable Class Library I writing the implementation in a project that I can share between platforms.

public class InsightsLogger : ILogger
{
     public virtual Task InitializeAsync()
     {
     }
 
     public void LogException(Exception ex)
     {
           Insights.Report(ex, ReportSeverity.Error);
     }
 
     public Task TrackAsync(string identifier, Dictionary<string, string> details = null)
     {
           Insights.Track(identifier, details);
     }
 
     public Task Identify(string userId, Dictionary<string, string> details = null)
     {
          Insights.Identify(userId, details);
     }
}

The InitializeAsync method is virtual so it can be overridden, when using Xamarin Insights each platform has to have the Initialize code. Because of that I also need to create a logger class for each platform.

While I don’t want errors from development together with production data I use to create two apps in Insights, one for development and one for production. I using conditional compile for to initialize with the right app key.

 public class WinPhoneInsightsLogger : Logging.InsightsLogger
    {
        public override async Task Initialize()
        {
#if DEBUG
            Insights.Initialize("key for debug use");
#else
            Insights.Initialize("key for production use");
#endif
        }
    }

if you want to read more about Xamarin Insights you can do it here, http://xamarin.com/insights

Crossplatform and storage strategies

Many applications need to store data related to the application. If you’re building applications for multiple platforms the APIs for storage is different.

Following five storage types is the most common ones:

Local storage
Storage to store application data locally on the device.

Remote storage
Storage to store application data in the cloud, for example OneDrive or iCloud. Data that is saved in the cloud could be accessible from different devices.

Cache storage
Storage to use when caching data. Platforms that have a separate storage for cache data will not contain cache storage in the backup, WinRT for an example. Cached data is not necessary to have in a backup, it will be cached again after restore of the backup.

Settings storage
Storage to store application settings locally on the device.

Remote settings storage
Storage to store application settings in the cloud, for example OneDrive or iCloud. Settings will be synced for all devices you have installed the application on.

You can handle storage in different ways, one strategy is to create one interface for each of the storage types above, for example ILocalStorage and IRemoteStorage. Every interface will have an implementation for each platform. With help of an IoC-container (Inversion of Control) we can use the interface to call platform specific code from shared code.

public interface ILocalStorage
{
     Task AddAsync(string key, object value);
     Task<T> GetAsync(string key, object value);
     Task<bool> ContainsAsync(string key);
     Task RemoveAsync(string key);
}

One other strategy is to create one storage interface, IStorage and have a method with storage type as an argument. As with the first strategy each platform will have a platform specific implementation that can be used from shared code with help of IoC.

public enum StorageTypes
{
    Local,
    Remote,
    Cache,
    Settings,
    RemoteSettings
}
 
public interface IStorage
{
     Task AddAsync(string key, object value, StorageTypes storageType);
     Task<T> GetAsync(string key, object value, StorageTypes storageType);
     Task<bool> ContainsAsync(string key, StorageTypes storageType);
     Task RemoveAsync(string key, StorageTypes storageType);
}
 
public class Storage : IStorage
{
     public async Task AddAsync(string key, object value, StorageTypes storageType)
     {
          switch(storageType)
          {
                 case StorageTypes.Local:
                      //code for local storage
                      break;  
                 case StorageTypes.Remote:
                      //code for remote storage
                      break;  
                 case StorageTypes.Cache:
                      //code for cache storage
                      break;  
                 case StorageTypes.Settings:
                      //code for settings storage
                      break;  
                 case StorageTypes.RemoteSettings:
                      //code for remote settings storage
                      break;  
          }     
     }

I prefer the first strategy beacause I like small classes with one role, the maintainability will be much higher and you can make changes to one implementation without the risk of breaking other functionality than that one you want to change.

As an example, one platform maybe don’t have CacheStorage, then the LocalStorage and CacheStorage will be pretty much the same. But if that platform will get CacheStorage in the future you can change the implementation of ICacheStorage without touching the working code for LocalStorage.

Xamarin.Forms and panorama in a Windows Phone app

One common scenario when building an app is that we want to use tabs on iOS and Android and a Panorama on Windows Phone. Xamarin.Forms has a control called TabbedPage that render tabs on iOS and Android. At the bottom of the page for iOS and at the top of the page under the ActionBar for Android, for Windows Phone a Pivot is rendered. To render a Panorama instead is a quite simple with conditional compile and a custom render.

Xamarin.Forms has a control that renders a Panorama on Windows Phone that is called CarouselPage. But we don’t want to use it for iOS and Android. The solution for that is to use conditional compile.

In the tab host page you want to inherit from CarouselPage instead of TabbedPage. To use conditional compile for the inheritance of the class we can’t have a XAML file for the page. The example below inherits from CustomCarouselPage, it is only an empty class that inherits from CarouselPage, the only reason is that we want to create a custom renderer for the CarouselPage.

#if WINDOWS_PHONE
    public partial class MainView : CustomCarouselPage
    {
#else
    public partial class MainView : ExtendedTabbedPage
    {
#endif

To get it work with conditional compile we also need to add “WINDOWS_PHONE” to conditional compile symbols under the Build tab on project properties for the shared project. I recommend to create a two new build configurations for the solution, I use to call them Debug_WP (copy settings from Debug) and Release_WP(copy settings for Release).

The CarouselPage doesn’t have titles for the panorama items. To fix that we need to create a custom renderer in the Windows Phone project. While we want to extend the default renderer we can inherit from CarouselPageRenderer. If we want to style the PanoramaHeader and the PanoramaItemHeader we can do it by creating templates and then add them to the Panorama as shown below.

[assembly: ExportRenderer(typeof(CustomCarouselPage), typeof(CustomCarouselPageRenderer))]
namespace MyApp.WinPhone.Renderers
{   
    public class CustomCarouselPageRenderer : CarouselPageRenderer
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);
 
            var titleTemplate = App.Current.Resources.SingleOrDefault(x => x.Key.ToString() == "PanoramaTitle").Value as System.Windows.DataTemplate;
            if (titleTemplate != null)
            {
                TitleTemplate = titleTemplate;
            }
 
            var headerTemplate = App.Current.Resources.SingleOrDefault(x => x.Key.ToString() == "PanoramaItemHeader").Value as System.Windows.DataTemplate;
            if (headerTemplate != null)
            {
                HeaderTemplate = headerTemplate;
            }
 
            for (int i = 0; i < Items.Count; i++)
            {
                var item = Items[i] as PanoramaItem;
                var page = Element as CarouselPage;
                item.Header = page.Children[i].Title;
 
                var content = item.Content as CarouselPagePresenter;
                content.Margin = new System.Windows.Thickness(0, -30, 0, 0);
            }
        }
    }
}

Here is an example how the templates in App.xaml (in the Windows Phone project) can look like:

 <Application.Resources>
        <DataTemplate x:Key="PanoramaTitle">
            <ContentPresenter>
                <TextBlock Text="{Binding}" FontSize="100" Foreground="#FFFFFF" Margin="0,40,0,0" />
            </ContentPresenter>
        </DataTemplate>
        <DataTemplate x:Key="PanoramaItemHeader">
            <Grid>
                <ContentPresenter>                  
                    <TextBlock Text="{Binding}" FontSize="30" Foreground="#FFFFFF" Margin="-10,20,0,0"  />
                </ContentPresenter>
            </Grid>
        </DataTemplate>
    </Application.Resources>

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>

Modern UI icons

If you searching for icons for your app or website, check out http://modernuiicons.com/. There are over 1000 icons designed for your app or website. It is a very good library when building modern UI apps for Windows Phone, Windows 8 or iOS7. But I have also used them for different websites. When I searching for icons I almost always finds an icon in Modern UI icons library.

When you download the library you will get a dark and a white version of the icon. But you also got them in the vector format, .design and .svg.

Travelling with my Lumia

For a couple of weeks was me, my girlfriend and a friend visiting Unites States, we visiting New York and drove around by car at the west side of the country. Under the two weeks we was there we travelled over 400 miles by car.

To navigate we used my Nokia Lumia 920 and the Here Drive+ apps that comes with all Nokia Windows Phones. I have downloaded all maps before we left Sweden.

I was a little bit unsure how it will worked before, but people on a Swedish group for Windows Phone users told me that it will work fine. I have used it in Sweden with good result earlier but I asked for to be sure. All we talked about before told us it was a good idea to bring a GPS.

The people on the Windows Phone group had right it worked very well, I am impressed that a free app could work so good (it coast a few dollar if you do not have a Nokia, but it definitely worth it). We used it not just when we went by car, but also when we walking in big cities like New York.

To have something to attach the phone to I brought my Nokia CR-200 holder with build in wireless charging that I bought earlier this summer.

To use my Windows Phone instead of renting a GPS, we saved pretty much money that we could use for other things.

If you is to buy a new phone, just Here Drive+ is a reason enough to buy a Windows Phone.

 

Nokia CR200

Beyond the Tiles

Monday was me, Johan (@johankson) and David(@d_andersson) visiting Microsoft for a seminar about design, primary for Windows 8 and Windows Phone. Arturo Toledo (@arturot), Alex Toledo (@toledoal) and Vincent Garcia (@vincentgarcia) was the speakers at the seminar. Arturo is a former member of Microsofts Windows Phone team but now he has his own company, Toledo2, together with his brother Alex. The third speaker Vincent Garcia are working with design for Windows 8 and Windows Phone at Avanade Digital.

The Toledo brothers start the day by giving us a lesson in design history and talked about the Swiss design school and the international style. It’s there the Metro design or Microsoft design language as it’s called today, has its roots.

One of the message of the day that Microsoft design language is much more than tiles, thereof “Beyond the Tiles”. They say the developers of Windows apps follow the guidelines to much and that make all Windows apps look the same, many developers use the Visual Studio templates and thinks the design has to be in that way.

Vincet Garcia showed us a couple of designs he had done for Windows 8 and Windows Phone and how the design has evolve with their increased understanding of the design language.

We also get som tip how we could improve the design of the Windows 8 version of WordRoom, thanks for that!

It was a good day and I became inspired and get much new knowledge to use in coming designs.

 

Size limit on app download when using 3G

iOS and Windows Phone has size limit on how big apps you can downloaded when you’re not connected to a Wi-Fi-network. Windows Phone has a limit on 20 Mb and iOS has 50 Mb.  Android has not that type of limit, but an APK on Google Play is limited to 50 Mb, but you can add extensions that are much bigger than so.

When are you downloading apps to your phone? It’s often when you sitting on the bus or waiting for something. Do you have a Wi-Fi-connection then? Often not.

I think it could be a good thing to think about when developing apps. If a user found your app and cannot download it, the chance that they choose to download another app instead is big. If you have big content in you app, you maybe can have it on a server and download it when the user starting the app.

Probably the user don’t need that content from start and you have some time to download it, if they navigate to a part that need the content, show a loading dialog that tells the user that content is under download.

Developing apps with mono

WordRoom started as a Windows Phone project, the third client we started to develop and the first one we released was for Windows 8. We developed the windows 8 relative fast because we could reuse a lot of the code from the Windows Phone project in that we used portal library for the core logic.

As I mentioned above, Windows 8 was the third client we started to develop. The second was for android devices. I started to build the android client with java and eclipse. Step one was to translate all core logic from C# to java, a lot of work but I developed an almost finished client for WordRoom. But in the end of 2012 when we should start to develop the client for iOS we decided to use and mono touch and mono for android from Xamarin so that we could use the same assemblies for the core logic that we did when developing for the Windows platforms. We also share data contract assemblies between the backend and the clients. So now we running the same code in at backend in Windows Azure, on Windows 8, Windows Phone, Android and iOS.

The decision to start using mono is one of the best decision we have taken. We saving a lot of time and we get an app that is much easier to maintain.

Next app I will develop I will think about that that the code will be shared between different platforms earlier in the process. Because if you have a structure in your project with GUI and business/game logic split up and using interfaces for platform specific features, for example local storage you can reuse much more code and save a lot of time.