Caliburn.Micro Xaml made easy

Working with Compiled Bindings on Windows 10

I’ve had a few people ask me how Caliburn.Micro will work with compiled bindings in Windows 10. Here’s a brief summary based on I know from chatting to some of the engineers at Microsoft.

Overview

For those who aren’t familiar with them (most people given it’s a new technology), compiled bindings are a way to have the compiler generate static code for a binding rather than using a dynamic binding that depends on reflection. This increases performance quite a bit and can be used quite heavily, there’s also some features where you can bind an event to a method.

What used to be:

<TextBox Text="{Binding Username, Mode=TwoWay}" />

becomes (where ViewModel is a strongly typed property on the view)

<TextBox Text="{x:Bind ViewModel.Username, Mode=TwoWay}" />

To get a better understanding I’d recommend watching Sam Spencer’s Build talk Data Binding: Boost Your Apps’ Performance Through New Enhancements to XAML Data Binding

Working with Caliburn.Micro

Out of the box Caliburn.Micro checks properties for existing bindings before applying conventions. For instance this stops the convention for SomePropertyName overwriting the existing Binding.

<TextBox x:Name="SomePropertyName" Text="{Binding Username, Mode=TwoWay}" />

Unfortunately there is no programmatic way to test if a DependencyProperty has a compiled binding, which means that if you’re mixing convention based binding and compiled bindings there is a chance they could collide.

<TextBox x:Name="SomePropertyName" Text="{x:Bind ViewModel.SomeOtherProperty, Mode=TwoWay}" />

Interestingly because a compiled binding isn’t a real binding then the convention doesn’t overwrite the compiled binding but they exist in parallel which will most likely just confuse everyone.

I’d recommend using one or the other and not mixing them both. You can potentially save yourself some pain and get a performance increase by disabling conventions either on a per view basis

<Page cm:View.ApplyConventions="false">

or on a global basis.

ViewModelBinder.ApplyConventionsByDefault = false;

Of course Windows 10 is still in preview and things could change.

Caliburn.Micro 3.0.0-alpha

I’m really pleased to announce the release of Caliburn.Micro 3.0.0-alpha, this is a major milestone in that it adds support for three new platforms Xamarin.iOS, Xamarin.Android and Xamarin.Forms. This is an early alpha in order to get feedback and testing from the wider community (which is now a lot bigger thanks to this release).

Xamarin.iOS & Xamarin.Android

In a previous post I broke down Caliburn.Micro in to a box diagram of features.

Caliburn.Micro Overview

I also talked about how a lot of the features don’t make sense for non XAML platform such as Xamarin.iOS and Xamarin.Android. Over the course of the alpha I expect there’ll be discussion about how we can apply some Caliburn-esque features into Xamarin app development.

In 3.0.0-alpha we have the full portable assembly working against Xamarin and as well as the IPlatformProvider and the ViewModelLocator. The goals here are to have the ability to share your view models and their patterns such as event aggregation and view model composition over all the platforms using Portable Class Libraries, while building native apps with their normal patterns such as Activities and View Controllers.

ViewModelLocator is a good example of what I mean by differences with non XAML platforms that ViewModelLocator on Android expects something like MyApp.Activities.LoginActivity and resolves to MyApp.ViewModels.LoginViewModel.

A sample of this sort of app is can be found at Hello.Xamarin in the GitHub repository.

Known Issues

  • The current Storyboard designer for iOS in Visual Studio doesn’t respect the folder / namespace it’s placed in when generating types, as such the current conventions for view model locator MyApp.ViewControllers.LoginViewController to MyApp.ViewModels.LoginViewModel may not make sense in the long term.

Xamarin.Forms

This alpha also brings support for Xamarin.Forms which in abstraction layer over the different UIs in iOS, Android and Windows Phone Silverlight (Windows 8 / 10 support coming later). What’s really interesting is that it comes with it’s own XAML syntax (not the same as Windows XAML but very similar), this means we can get a closer to standard Caliburn.Micro experience. I was pleasantly surprised by how much I got ported reasonable easy.

A sample of this sort of app is can be found at Hello.Forms in the GitHub repository.

One of the more interesting features here is that Xamarin.Forms runs on top of the existing mobile platform (Xamarin.iOS, Xamarin.Android and Windows Phone Silverlight). This makes it the first version where two different platforms of Caliburn.Micro have to run side by side. We essentially have two instances of ViewModelLocator, one in Caliburn.Micro.ViewModelLocator for the current host platform and one at Caliburn.Micro.Xamarin.Forms.ViewModelLocator if Xamarin.Forms is present.

Known Issues

  • There is no programmatic access to x:Name in Xamarin.Forms, therefore the feature of name based conventions will not be available, you will need to use normal {Binding Username} and cm:Message.Attach="SignIn".
  • There is no way to check to see if a BindableProperty has a Binding set. Thankfully we only use this ensure name based conventions don’t overwrite existing bindings, given the first issue this is currently less of a problem.
  • I’m not entirly happy with FormsApplication and that both Caliburn.Micro and Xamarin.Forms want to set a custom UIApplicationDelegate, we’ll need a better way of playing together nicely.

Breaking changes

Right now there are no breaking API changes for the existing platforms there are some ABI ones, given the new multi-platform scenario described above I’ve introduced a new assembly Caliburn.Micro.Platform.Core that holds some of the internal classes used the various platform assemblies. This lets us have to platforms at the same time without any type collision.

If you’re using nuget then this new assembly will automatically be referenced, but if you’re doing any sort of manual references you may need to check this out. I’ve applied this change to all the “modern” platforms (.NET 4.5, Windows Phone 8, Windows 8, Windows 8.1 Windows Phone 8.1, Xamarin.iOS and Xamarin.Android). Due to the PCL profile restrictions the .NET 4.0 and Silverlight 5 platforms work as they previously did.

As the alpha progresses I expect there will be breaking changes on the Xamarin platforms, and I don’t expect many if any changes on the others.

How do I get this?

For Xamarin.iOS and Xamarin.Android simply use the normal Nuget package Caliburn.Micro, if you’re wanting to checkout Xamarin.Forms then use the package Caliburn.Micro.Xamarin.Forms.

The code for these releases will most likely stay on the Xamarin branch till it’s closer to being finalised.

What about Windows 10?

At the time of writing this we can’t yet release anything for Windows 10 because there is no framework identifier in Nuget and we only have an alpha of the tools. The Windows 8.1 version works perfectly well in building a Windows 10 app, but I’ve already started working on the Windows 10 version on a separate branch which you can build and use. This adds conventions and binding scope changes for the new controls and creates a single platform for Windows 10 Desktop, Tablets and Phone (and potentially Xbox and HoloLens).

Once the Windows 10 tools are finalised, I would expect to announce something soon after.

The road ahead

There’s a lot of things still to do in this alpha, mostly around the new platforms other than Xamarin.Forms and what features can be brought to them. With new platforms comes new documentation (the website could definitely do with a documentation upgrade) and associated tutorials / blog posts.

I also want to extend both of the sample mentioned above, they’re very bare bones right now.

If you want to follow the process going forward and want to participate checkout the Xamarin - Native & Forms issue on GitHub.

The code for these releases will most likely stay on the Xamarin branch till it’s closer to being finalised.

Thanks

A massive thank you has to go to Marker Metro here who essentially sponsored all the time it took me to put this 3.0.0-alpha together.

Marker Metro

Windows 10 Universal App Platform & Caliburn.Micro

Yesterday Microsoft released the Windows 10 Technical Preview tools. I’ve finally managed to get a chance to test out Caliburn.Micro on the new platform and can quickly talk about building these apps using Caliburn.Micro.

Installing

Out of the box Windows 10 can use Windows 8.1 assemblies with no changes so using the Windows 8.1 version of Caliburn.Micro will work. Just carry on as you normally do and add a nuget reference, Visual Studio 2015 will use the Win 8.1 assemblies in the package (and checkout out the new nuget UI at the same time).

The nuget package does add a reference to the Behaviours SDK as part of the install.

Update: I was wrong about the Behaviours SDK, after reading the release notes the problem is that the platform can’t reference Windows 8.1 extensions. You should follow the release notes work around. Which is to copy the extension from C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1\ExtensionSDKs to C:\Program Files (x86)\Microsoft SDKs\UAP\v0.8.0.0\ExtensionSDKs and a reference in your project by adding the following to your csproj.

<ItemGroup>
  <!-- A reference to the entire .NET Framework and 
         Windows SDK is automatically included -->
     <SDKReference Include="BehaviorsXamlSDKManaged, Version=12.0">
    <Name>Behaviors SDK %28XAML%29</Name>
  </SDKReference>
</ItemGroup>

Platforms

Because the platform picked the Windows 8.1 assemblies to reference we don’t have access to any specific Windows Phone 8.1 functionality which is currently limited to the INavigationService.BackPressed event.

Releases of Caliburn.Micro that specifically target this platform will correct this.

The Future

Overall this new platform won’t have a major impact on Caliburn.Micro has it’s incredibly similar to Windows 8.1. We will need to add some new functionality to make use of the new controls such as SplitView and the like and I’m really looking forward to being able to announce Caliburn.Micro running on an Xbox.

You can follow progress on this at GitHub.

Xamarin & Caliburn.Micro

With the cross section of the following technologies increasing amounts of code are being shared across multiple platforms.

  • Portable Class Libraries
  • Shared / Universal Apps & Projects
  • Xamarin (Native)
  • Xamarin.Forms

The idea that we can write our model (thinking in MVVM terms) once and share it across a wide array of platforms. There’s also some appeal to be able to share your view models in the same way.

With Caliburn.Micro we could do this already for the Microsoft XAML platforms. Your view models could be declared in a PCL that references Caliburn.Micro.Core and add something similar to the following code in your app.

ViewModelLocator.AddNamespaceMapping("Example.App.Views", "Example.App.Portable.ViewModels");

The use of Xamarin raises a lot questions.

  • Can we share our view models on Xamarin platforms?
  • What would Caliburn.Micro on Xamarin.Android and Xamarin.iOS even look like?
  • How does Xamarin.Forms fit in to this?

Well the good news is that we’ve started work on bringing Caliburn.Micro to Xamarin and this post is to discuss a potential roadmap and pose some questions to you the community.

Below is a really simple breakdown of the feature-set of Caliburn.Micro and how it’s split between the Portable and Platform Assemblies.

Caliburn.Micro Overview

If we’ve built things right then everything that’s in the Portable assembly will already be ready for use in Xamarin apps. The only part that would be required in the Platform assembly is the piece highlighted below, the Platform Provider. This allows the Portable assembly to do things such as ensuring property changed notifications happen on the UI thread.

Caliburn.Micro Xamarin Initial

I’m really happy to say we have this mostly completed and available on the xamarin branch in GitHub. You can now share your view models across all the XAML platforms as well as Android and iOS!

You can see the start of some of these demonstrations at nigel-sampson/xamarin-experiements.

So where to from here? Part of the discussion I want to foster is which the grey boxes above make sense outside of a XAML framework and in what way do they make sense in these other platforms?

Could we add similar but not exactly the same features on these platforms such as ActivityLocator instead or ViewLocator?

Some of these features make a lot more sense when we consider Xamarin.Forms which is a XAML-like platform. We’d like to keep that as a separate assembly to ensure we don’t end up requiring certain editions of Xamarin. It would also need to be development in a way that Xamarin native development worked hand in hand with Xamarin.Forms.

We’re certainly not promising and exact version of Caliburn.Micro on Xamarin but the most we can speed up your development using similar patterns across multiple platforms the better we’ll all be.

The future is bright!

2.0.2 point release

We’ve just pushed 2.0.2 to nuget, it’s a small release mostly with bug fixes missing from 2.0.0.

What’s New?

  • Resolved some design time bugs.
  • PropertyChangedBase.Refresh is now virtual.
  • Added checks to guard against an async CanClose.
  • Allow SettingsWindowManager to open independent flyouts [WinRT].
  • Deal with unicode in C# identifiers.
  • AttachedCollection.On* methods are now virtual.
  • ViewAware.GetView is now virtual`.
  • ViewLocator.LocateForModel falls back to LocateForModelType if the view could not be added to the visual tree.
  • ActionMessage.UpdateAvailablility is now virtual.
  • Removed explicit garbage collection from WinRT FrameAdapter.
  • Resolved a bug where couldn’t navigate to a view model that contained the name of the assembly.

Thanks to all who contributed fixes, logged bugs etc.