Our Discord community is buzzing. Come and join us!

Migrating a Custom-Drawn Xamarin Forms Control to Uno Platform

In a previous blog post, we explored porting a Xamarin Forms control which was made up of standard XAML elements over to Uno Platform. This time we will investigate a custom-drawn control and provide source code for it. While there are many ways to custom-drawn controls, the main implementation you will come across on a multi-platform Xamarin Forms control is SkiaSharp. SkiaSharp is a cross-platform .NET API based on the Skia 2D graphics library. Skia was created by Google but is available on all mainstream platforms and so you can create drawing code which works across devices regardless of their specific implementation. SkiaSharp therefore runs across all .NET mobile and desktop platforms.  

When building a custom control for Xamarin Forms you can use the SKCanvasView. This provides a View which contains the OnPaintSurface method which you implement in your derived class to draw to the screen. The method arguments contain to the SKSurface which represents the raw surface you can draw to. The SKCanvasView handles resizing and will call your OnPaintSurface method to redraw as required. Your code will consider the size of the surface as you should expect this to vary between devices or at runtime due to screen rotation or moveable UI elements. 

Skia and Uno Platform

Luckily the SkiaSharp project already has support for the Uno Platform and it is available on NuGet in the SkiaSharp.Views.Uno package. The SKXamlCanvas control is the equivalent to the SKCanvasView we described above but it inherits from the WinUI Canvas class. This control handles lifecycle and size changes and contains an overridable OnPaintCanvas method where you can draw to the surface. 

Knowing this we can see that we probably don’t need to change any of the SkiaSharp code from an existing control – we simply create a library with a class derived from SKXamlCanvas and hook up the drawing logic from the Xamarin Forms, Windows or any other variant of a SkiaSharp based control. 

Porting Microcharts

Microcharts is a simple open-source charting library written in C# and utilizing SkiaSharp to draw a wide range of chart types. It had implementations for Xamarin Forms, .NET MAUI, UWP and others but up until now no Uno support. The great thing about having UWP support already there is that the code was already written for the Windows version of SKCanvasView and so can be used with minimal changes in an Uno library.  

Therefore, to add Uno support we needed to add a new project – Microcharts.Uno.WinUI. This is created as a .NET Standard library so has no platform dependencies itself. We add a reference to SkiaSharp.Views.Uno.WinUI, and Uno.WinUI. Because the SkiaSharp.Views libraries depend on the base SkiaSharp library you don’t need to explicitly add this too. Finally, we add a link to the existing UWP ChartView.cs. 

The only necessary changes in the code were to support WinUI 3.0 (and hence the Uno.WinUI implementation too) by changing the using statements. This is handled using an #if directive so that the single file can be retained in multiple projects:

					#if WINUI 
    using Microsoft.UI.Xaml; 
    using SkiaSharp.Views.Windows; 
    using Windows.UI.Xaml; 
    using SkiaSharp.Views.UWP; 

As described above the drawing is carried out by the OnPaintCanvas method which looks like this:

					private void OnPaintCanvas(object sender, SKPaintSurfaceEventArgs e) 
   if (this.chart != null) 
      this.chart.Draw(e.Surface.Canvas, e.Info.Width, e.Info.Height); 

The chart object is an instance of Microcharts.Chart and is the same across all implementations of Microcharts. It contains the Draw method which takes the Skia canvas and size and does all the drawing based on the properties set on it and the data source. This means that on all platforms you can access the Chart property via XAML or code and have the same API regardless of platform. 

Using Microcharts in an App

Now that we have a library built to support Microcharts in Uno, we can integrate it into an app. The Microcharts.Samples.Uno project is built using the Uno new project template and consists of a shared project containing the XAML and code-behind for the app. This sits alongside header projects for each platform – Windows, Mobile and Skia.GTK. These reference another project Microcharts.Samples which contains example data used by all the various sample projects. This shows how it is easy to share or port code between these different .NET platforms as all the logic is platform-agnostic. 

Uno Platform sample showing six different chart styles

Next Steps

You can access all the code for Microcharts, including the Uno libraries and Sample app, in the GitHub repository. The Microcharts.Uno package will also be available on NuGet soon to easily integrate the binaries into your own app. 

To upgrade to the latest release of Uno Platform, please update your packages to 4.7 via your Visual Studio NuGet package manager! If you are new to Uno Platform, following our getting started guide is the best way to get started . (5 min to complete)

Share this post:

Uno Platform 5.2 LIVE Webinar – Today at 3 PM EST – Watch