Caliburn.Micro Xaml made easy

Caliburn.Micro 3.0.0 released

I’m really pleased to finally announce the release of Caliburn.Micro 3.0.0 after a long period of being in beta. The major features of 3.0.0 are Windows 10 / UWP and Xamarin.Forms support. With this release you can use your view models across all major platforms that support C#!

It’s important to note this is a change in the major versions to there may be breaking changes.

Windows 10

The Windows 10 release follows along with the Windows 8.1 and Windows Phone 8.1 releases and combines them into a single library which is great from a maitenance perspective. If we need to start adding features specific to Phone, Xbox or even HoloLens they’ll be done using feature detection via Windows.Foundation.Metadata.ApiInformation.

It includes conventions for new controls such as SplitView.

Also included is a sample showing how to set up a SplitView style app with the Frame not being the root visual but inside the ShellView, this sample is available at Hello UWP.

We now use the new open sourced XAML Behaviours package.

Windows 8.1

  • Fix for transparent tiles in App Manifest Helper

Windows 8.0

This release drops support for Windows 8.0 (different from Windows 8.1).

Xamarin Forms

This release 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.

There are some limitations of the Xamarin.Forms flavour of of XAML, primarily there is no programmatic access to x:Name mean we cannot support named based conventions. We can still support attached properties such as cm:Message.Attach as well as convention based view / view model location.

<ListView ItemsSource="{Binding Features}" HasUnevenRows="True"
          cm:Message.Attach="[Event ItemSelected] = [ShowFeature($selectedItem)]">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <ContentView cm:View.Model="{Binding}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"/>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Also included is the now standard navigation service and navigation helper methods

navigationService.For<ProductViewModel>()
    .WithParam(v => v.ProductId, 42)
    .Navigate();

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.

Xamarin.iOS and Xamarin.Android

This release primarily targets Xamarin.Forms, however work has been done to allow your view models to be reused within a Xamarin.iOS or Xamarin.Android applications with no support around binding or conventions.

These features will be added in later feature releases.

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

Preserving State

One new feature in this release is the CachingFrameAdapter. This subclass of FrameAdapter (which implements INavigationService in WinRT platforms such as Windows 8.1, Windows Phone 8.1 and Windows 10) will cache internally view models and reuse them on the appropriate navigation. This allows scenarios where the built in NavigationCacheMode doesn’t make sense but still preserve your view model state. A sample of this in action is available at Caliburn.Micro.State.

Other Changes

  • Resolved a WPF bug using MainWindow when it’s disposed.
  • Resolved ViewLocator.LocateForModelType failing to deal with improperly reused views in WinRT.
  • Resolved a premature garbage collection issue in Action.Invoke.
  • Removed a unnecessary explicate collection in FrameAdapter.
  • BindingScope has been cleaned up a lot so will be easier to extend.
  • Async methods are now taken into account for conventions. CanLogin will be used as a guard for LoginAsync and will be attached to a control with xName="Login".
  • Better handling of scenarios where a root frame is not being used with the navigation service.
  • Removed the case sensitivity when adding custom special values to MessageBinder.
  • Screen.IsActive, Screen.IsInitialised and PropertyChangedBase.IsNotifying are now virtual, we don’t see then behaviour being overriden but a lot apps will need to add their own custom attributes to these properties.

Breaking Changes

  • The extensions projects have moved into the main platform assembly, these were initially created as a place for very platform specific code but they’ve outlived there usefulness and removing them reduces some maintenance costs.
  • Bind.Model had a feature enabling you to pass a string which used IoC to find the model. This was deprecated in 2.0.0 and has now been removed.
  • SimpleContainer now only uses public constructors.
  • The UriFor method has been deprecated in favour of just For given the lack of uri support on a number of platforms.
  • WinRT platforms now make use of AssemblySourceCache which means if your view models do not implement INotifyPropertyChanged or views subclass from UIElement then they may not be found by ViewLocator or ViewModelLocator. This behaviour can be changed by modifying AssemblySourceCache.ExtractTypes.

Thanks

Thank you to all who have contributed fixes, reported issues and generally feedback on the extended pre-release versions.

As well a bit thanks to Marker Metro who sponsored a lot of the time it took me to put this 3.0.0 release together.

Caliburn.Micro 3.0.3 released

I’ve just pushed the 3.0.3 release of Caliburn.Micro to nuget.

This release reverts #339, this PR changed the way Caliburn.Micro resolved views from the container.

Previously the framework only called GetAllInstances to attempt to resolve the view, relying on the fact that most containers wouldn’t error when the view wasn’t resolved.

View Models however were resolved using GetInstance. #339 made this consistent calling GetInstance for both.

This was noted as a breaking change and included in 3.0.2 by mistake, it should not have been included as it caused exceptions when the developer was using an IoC container that threw exceptions on dependency resolution expcetions such as Autofac.

Since the release it’s become apparent this has been a problem so 3.0.3 reverts this change.

Apologies to anyone affected by this.s

Caliburn.Micro 3.0.0-beta1

I’m really pleased to announce the release of Caliburn.Micro 3.0.0-beta1, this is a major milestone in that it adds support for a new platform Universal Windows Platform / Windows 10 as well as for the three new platforms Xamarin.iOS, Xamarin.Android and Xamarin.Forms added in 3.0.0-alpha.

This is an early beta in order to get feedback and testing from the wider community (which is now a lot bigger thanks to this release).

All the release notes from 3.0.0-alpha apply to this release as well.

Windows 10

The Windows 10 release follows along with the Windows 8.1 and Windows Phone 8.1 releases and combines them into a single library which is great from a maitenance perspective. If we need to start adding features specific to Phone, Xbox or even HoloLens they’ll be done using feature detection via Windows.Foundation.Metadata.ApiInformation.

Also included is a sample showing how to set up a SplitView style app with the Frame not being the root visual but inside the ShellView, this sample is available at Hello UWP.

Preserving state

One new feature in this release is the CachingFrameAdapter. This subclass of FrameAdapter (which implements INavigationService in WinRT platforms such as Windows 8.1, Windows Phone 8.1 and Windows 10) will cache internally view models and reuse them on the appropriate navigation. This allows scenarios where the built in NavigationCacheMode doesn’t make sense but still preserve your view model state. A sample of this in action is available at Caliburn.Micro.State.

Xamarin Forms

  • Included NavigationHelper which adds the For<TViewModel> method to allow easier view model navigation.
navigationService.For<ProductViewModel>()
    .WithParam(v => v.ProductId, 42)
    .Navigate();

Other Changes

  • Resolved a WPF bug using MainWindow when it’s disposed. Thanks dvdorle.
  • Resolved ViewLocator.LocateForModelType failing to deal with improperly reused views in WinRT.
  • Resolved a premature garbage collection issue in Action.Invoke.
  • Removed a unnecessary explicate collection in FrameAdapter.
  • BindingScope has been cleaned up a lot so will be easier to extend.

Breaking Changes

All the breaking changes from 3.0.0-alpha apply to this release as well.

  • The extensions projects have moved into the main platform assembly, these were initially created as a place for very platform specific code but they’ve outlived there usefulness and removing them reduces some maintenance costs.
  • Bind.Model had a feature enabling you to pass a string which used IoC to find the model. This was deprecated in 2.0.0 and has now been removed.
  • SimpleContainer now only uses public constructors. Thanks belyansky.
  • The UriFor method has been deprecated in favour of just For given the lack of uri support on a number of platforms.
  • WinRT platforms now make use of AssemblySourceCache which means if your view models do not implement INotifyPropertyChanged or views subclass from UIElement then they may not be found by ViewLocator or ViewModelLocator. This behaviour can be changed by modifying AssemblySourceCache.ExtractTypes.

How do I get this?

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

Previously the code for all these new features was spread across a number of branches, it’s now consolidated in a single 3.0.0 branch.

Where to from here?

  • More Xamarin testing.
  • Expand on the platform specific samples.
  • Expand on the platform specific documentation.

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