Update on WinRT Support

Topics: Actions & Coroutines, Bootstrappers & IoC, Bugs, Conventions, Extensibility, Feature Requests, Framework Services, Getting Started, UI Architecture
Coordinator
Aug 2, 2012 at 8:25 PM

Thanks to the fantastic work of Nigel Sampson and Keith Patton we now have support for the full Caliburn.Micro feature set on WinRT. This is he initial port…and its not an official release yet, so there’s bound to be bugs. But if you want to use CM to build your WinRT app, please start using this code and help us iron out the kinks….and naturally start enjoying the CM way of building apps on WinRT.

Aug 3, 2012 at 11:15 AM

Thanks for that Rob, for everyone else I'm currently experimenting with integrating Windows 8 features such as Share and Settings. I've got some examples of this in my fork and would love any feedback.

Aug 3, 2012 at 9:06 PM

This is just great! Thank you for the hard work!

Based on the current code, I posted a "Getting Started" guide about the Caliburn.Micro for WinRT in here: http://mikaelkoskinen.net/post/caliburn-micro-winrt-getting-started.aspx

I just noticed that there seems to be support for async/await too? So I can write my method inside the view model like this:

        public async Task SayHello()
        {
            var dlg = new MessageDialog("Hello from caliburn.micro!");
            await dlg.ShowAsync();
        }

And the View is automatically bound against the method. Fantastic!

I wonder, what do you think if the Screen's OnInitialize and OnActivate -methods were changed from void to async task? This way for example the OnInitialize method could be easily used to call the services:

        protected async Task OnInitialize()
        {
            var data = await service.GetData();
            var anotherData = await service.GetOtherData(data);
            this.Items.AddRange(anotherData);
        }

Aug 4, 2012 at 9:28 AM

Technically async methods don't need to return Task, they can be "async void". There are a couple of things to note here though, async void methods can't be "awaited" which I believe makes sense in this scenario. Caliburn shouldn't be awaiting your methods. The other tricky issue is that async void methods swallow exceptions so you'll need do your own error handling. I think long term some solution involving Filters could work here.

All in all I think leaving the Screen lifecycle events as void that you can optionally make async is the best solution, same with methods exposed as Actions. I think there could be some really interesting patterns with coroutines and async but I'm still playing around with that.

Aug 7, 2012 at 6:46 AM

Thanks Rob, Keith and Nigel for getting this done.  It's great to be able to use.

One question for Rob,  In your implementation of PropertyChanagedBase you left out the change below from the fork for NotifyPropertyChange.  Just wondering what the rationale was there.  This seems it would really clean up setters and remove unwanted strings from my code.  Or am I missing something obvious?

#if WinRT 
public virtual void NotifyOfPropertyChange([CallerMemberName]string propertyName = "" )
#else
public virtual void NotifyOfPropertyChange(string propertyName)
#endif

 

Thanks again to everyone who is working on this ... its much appreciated!
 

 

Aug 7, 2012 at 7:07 AM

I believe I checked this in after Rob brought the changes across, in the next week I'll be able to do some more work on this. In particular some better extensions into Caliburn Application to deal with launching via tiles or the search charm. 

Aug 9, 2012 at 5:12 AM
Edited Aug 9, 2012 at 5:13 AM

Great work so far ;-)

@Nigel:
Is there a reason why you used the source of "Windows.UI.Interactivity" instead of the nuget package?

Aug 9, 2012 at 5:36 AM

No reason, somehow I missed the fact there was a Nuget package, I'll shift my fork to that.

Aug 11, 2012 at 12:34 PM

After encountering a rather strange bug in my app, I noticed that the EventAggregator wasn't handling the messages in order. This is caused by the Execute.OnUIThread which is in the current WinRT version working asynchronously, not synchronously. There was some discussion about this issue some time back: http://caliburnmicro.codeplex.com/discussions/358342

I'm currently using the following code in order to make it synchronous:

            var dispatcher = Window.Current.Dispatcher;

            SetUIThreadMarshaller(action => InnerExecute(dispatcher, action).Wait());

        private static async Task InnerExecute(CoreDispatcher dispatcher, System.Action action)
        {
            if (dispatcher.HasThreadAccess)
                action();

            else await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => action());
        }

Let me know if there's a nicer way to write this :)

Aug 13, 2012 at 9:20 AM
Edited Aug 13, 2012 at 9:28 AM

I think a Pre-Release NuGet pacakge 1.4.0 would be great...

At first we should fix the most important issues in the main repository.

@Nigel: When do you think you will merge your fork back into main?
Also I submitted a pull request, may someone verify it please.