Included in last week’s Xamarin 3 release is Xamarin.Forms. What is Xamarin.Forms? “A cross-platform natively backed UI toolkit abstraction that allows developers to easily create user interfaces that can be shared across Android, iOS, and Windows Phone” (emphasis mine).
Other goodies in Xamarin 3 are a visual designer for Xamarin.iOS within both Visual Studio and Xamarin Studio, NuGet support, F# support, support for Shared Projects, and quite a few fixes and enhancements. As usual with Xamarin, there’s a lot of promise here, along with many rough edges.
As in prior releases, you still need a Mac to serve as a “Xamarin build host” for iOS support, but this is an Apple-imposed restriction. If you’re doing Windows Phone 8 (or Windows Phone Silverlight 8.1), you need to be working in Windows 8 and Visual Studio with the appropriate Phone SDK installed. There’s no support for Universal apps, Windows Store, or Windows Phone 8.1 store apps at this time.
It’s probably just me, but I find all the Xamarin version numbers confusing, and didn’t even know that I’d been working in Xamarin 2 previously. “Xamarin 3.0″ includes Xamarin Studio 5.0 and Xamarin VSIX 3.0 for Visual Studio support. Xamarin.Android is currently at 4.12, while Xamarin.iOS seems to be at 7.2.1.
Licensing also hasn’t changed, unfortunately. The Business edition, needed for Visual Studio support, still runs $999 per platform, per developer. The free Starter edition does not include support for Xamarin.Forms, while the Indie edition, which does, is $299 per platform, per developer.
The goal of Xamarin.Forms is rapid application development, and primarily targets enterprise apps. XF contains a gallery of about 40 common controls and a navigation abstraction, basically the essentials for a typical forms-style page or application. Controls in the gallery include:
- Pages – an abstraction of the Android Activity, iOS ViewController, or WP Page
- Layouts – composable containers such as Grid and StackLayout
- Views – the usual buttons, labels, text boxes, images, date and time pickers, and more
- Cells – combine a label with another visual element in tables and lists
Some might argue that there’s nothing particularly sexy about form controls, but allowing a developer to build the boilerplate parts of a UI once with non-platform specific abstractions – a Page
, a Label
, a ListView
, etc. – is pretty powerful. Add in rendering using the native controls of each target platform, and this really is quite sexy. Although Xamarin seems to see Forms as a prototyping tool, if you can rapidly build native apps for multiple platforms – with native user interfaces, native API access, and native performance – while working at the “right” level of abstraction, what’s not to like?
Customization per platform is provided too. You can write custom renderers, and drop into platform-specific implementations via the built-in DependencyService
. The DependencyService
is not intended for use as a general-purpose DI container, it’s more in the style of “platform enlightenment” used with some PCL implementations, although it can be used as a simple Service Locator too.
There are two additional features though, which make Xamarin.Forms really exciting: data binding and XAML.
Android and iOS have no built-in data binding support, although you can use a third party framework like MvvmCross to accomplish this. The data binding support in Xamarin.Forms feels quite familiar: one- and two-way binding, INotifyPropertyChanged
, INotifyCollectionChanged
, value converters, static resources, ItemsSource, data templates. Missing, however, is validation, and there’s no INotifyDataErrorInfo
implementation.
XAML! Most of the current Xamarin.Forms doc and samples seem to focus on writing the UI in code, but what’s better when building a UI than working in a visual designer to get immediate feedback on every change? Granted, wiring up your controls in code is powerful, but it’s not 1990. XAML to the rescue! Or maybe not quite yet. Tucked away in the documentation is the note “Xamarin.Forms is not compatible with pre-existing XAML visual designers.” Yep, the XAML for Xamarin.Forms cannot be opened in the visual designer of either Visual Studio or Xamarin Studio. At this time, you must hand edit your XAML. Although there is supposed to be Intellisense within the XAML code editor now, I couldn’t get it working. A few other missing pieces: breakpoints and debugging of XAML data bindings aren’t supported yet, and the current API-level documentation doesn’t show any XAML sample code to make hand editing easier.
It’s tempting to want to grab some XAML from an existing app, forgetting that Xamarin.Forms defines its own controls. So for example this:
<StackPanel Orientation="Vertical">
<TextBlock Text="Name" />
<TextBox Text="{Binding FullName}" />
</StackPanel>
might look like this in Xamarin.Forms:
<StackLayout VerticalOptions="FillAndExpand" >
<Label Text="Name" />
<Entry Text="{Binding FullName}" />
</StackLayout>
Also note that XAML files can be defined only in portable class libraries and shared projects: platform-specific projects don’t understand Xamarin.Forms.
Which brings me to another important piece of Xamarin.Forms: shared project support, also introduced by Microsoft in Visual Studio 2013 Update 2 for Universal Apps. Previously, platform-specific projects could reference a portable class library for shared content; with Xamarin 3 there’s now the option to use shared projects, in both VS and Xamarin Studio.
A “shared project” is not truly a VS or XS project, and won’t compile into a separate assembly. Instead the project, with a .shproj extension, imports a .projitems file containing all the shared project artifacts. Projects referencing the shared project will automatically include all shared artifacts. It’s a little like file linking, a common technique for sharing content among multiple platform-specific projects, and also supports compiler directives. Unlike file linking, the editing experience is much better, as the code editor now includes a “context switcher” which allows you to view and edit the file within the context of the target project.
As with Universal Apps, choosing between a PCL or shared project for shared content is a decision each team must make. A PCL can provide quite a bit of flexibility and potential reuse in other solutions and platforms and is usually separately testable, but also means deploying another assembly. A shared project allows you to compile each target project into a single assembly, so might be great for small apps.
One gotcha with a shared project is that the referencing target projects likely have different namespace and/or assembly names. If, for example, you define a local namespace in shared XAML (e.g., xmlns:local="clr-namespace:TipCalc;assembly=TipCalc"
) for shared value converters, you’ll need to use the same assembly name for all target projects too.
So, XAML and data binding, PCL and shared projects. What might a simple solution look like? While I haven’t yet written anything that’s not both derivative and butt ugly, I found these helpful:
- Introduction to Xamarin.Forms – This is really quite comprehensive, and the best place to start.
- Among the samples, TipCalc shows off XAML and data binding, while the Forms Gallery provides code for every control type. Both samples were written by Charles Petzold, which should be reason enough to go check them out.
CodeProject
Filed under: C#
Tagged: cross-platform, mobile, xamarin