Creating your first Windows Phone 7 with Caliburn Micro

Caliburn Micro is a small, yet powerful framework designed for WPF, Silverlight and WP7. It implements a variety of UI patterns for solving real-world problems. Patterns that are highlighted include MVVM (Presentation Model), MVP and MVC.

It’s “Convention over configuration” helps you build rapid application development faster , clean code and easy to data bind.

More on this can be find in this website : http://caliburnmicro.codeplex.com/

In traditional programming, most of us will be doing the application stuff layer like tombstoning, navigation exception, startup URIs in the App.xaml.cs. but if you are used to using a Bootstrapper then you might be surprised let’s say Caliburn Micro that if you use this framework, the App.xaml.cs will now be just this

public partial class App : Application

    {

        public App()

        {

            InitializeComponent();

        }

    }

So, where did this 100 lines of code went from? Because even in App.xaml, we’re going to remove the default code that adds the 4 States of the Phone (Launching, Activated, Deactivated, Closing) and chance it to this

<Application.Resources>
<local:Bootstrapper x:Key=”bootstrapper” />
</Application.Resources>

Now, we create a new class in our project, and let’s call it the Bootstrapper. This Bootstrapper is from Caliburn Micro and this framework automatically binds your properties to your View AND you can easily bind Commands to your controls!

public class Bootstrapper : PhoneBootstrapper
{
private PhoneContainer _container;
protected override void OnLaunch(object sender, Microsoft.Phone.Shell.LaunchingEventArgs e)
{
base.OnLaunch(sender, e);
}

protected override void Configure()
{
_container = new PhoneContainer(RootFrame);

_container.RegisterPhoneServices();

// _container.PerRequest<MainPageViewModel>();
AddCustomConventions();
}

static void AddCustomConventions()
{
ConventionManager.AddElementConvention<Pivot>(Pivot.ItemsSourceProperty, “SelectedItem”, “SelectionChanged”).ApplyBinding =
(viewModelType, path, property, element, convention) =>
{
if (ConventionManager
.GetElementConvention(typeof(ItemsControl))
.ApplyBinding(viewModelType, path, property, element, convention))
{
ConventionManager
.ConfigureSelectedItem(element, Pivot.SelectedItemProperty, viewModelType, path);
ConventionManager
.ApplyHeaderTemplate(element, Pivot.HeaderTemplateProperty, viewModelType);
return true;
}

return false;
};

ConventionManager.AddElementConvention<Panorama>(Panorama.ItemsSourceProperty, “SelectedItem”, “SelectionChanged”).ApplyBinding =
(viewModelType, path, property, element, convention) =>
{
if (ConventionManager
.GetElementConvention(typeof(ItemsControl))
.ApplyBinding(viewModelType, path, property, element, convention))
{
ConventionManager
.ConfigureSelectedItem(element, Panorama.SelectedItemProperty, viewModelType, path);
ConventionManager
.ApplyHeaderTemplate(element, Panorama.HeaderTemplateProperty, viewModelType);
return true;
}

return false;
};
}

protected override object GetInstance(Type service, string key)
{
return _container.GetInstance(service, key);
}

protected override IEnumerable<object> GetAllInstances(Type service)
{
return _container.GetAllInstances(service);
}

protected override void BuildUp(object instance)
{
_container.BuildUp(instance);
}
}

Now, the next question for you guys is, how will you now handle tombstoning your applications? If you notice that there this Bootstrapper must Inherit from the PhoneBootStrapper class, and what does it contain?

public class PhoneBootstrapper : Bootstrapper
{
private bool phoneApplicationInitialized;
private PhoneApplicationService phoneService;

public PhoneApplicationFrame RootFrame { get; private set; }

public PhoneBootstrapper()
: base(true)
{
}

protected override void PrepareApplication()
{
base.PrepareApplication();
this.phoneService = new PhoneApplicationService();
this.phoneService.add_Activated(new EventHandler<ActivatedEventArgs>(this.OnActivate));
this.phoneService.add_Deactivated(new EventHandler<DeactivatedEventArgs>(this.OnDeactivate));
this.phoneService.add_Launching(new EventHandler<LaunchingEventArgs>(this.OnLaunch));
this.phoneService.add_Closing(new EventHandler<ClosingEventArgs>(this.OnClose));
this.Application.ApplicationLifetimeObjects.Add((object) this.phoneService);
if (this.phoneApplicationInitialized)
return;
this.RootFrame = this.CreatePhoneApplicationFrame();
((Frame) this.RootFrame).add_Navigated(new NavigatedEventHandler(this.OnNavigated));
this.phoneApplicationInitialized = true;
}

private void OnNavigated(object sender, NavigationEventArgs e)
{
if (this.Application.RootVisual == this.RootFrame)
return;
this.Application.RootVisual = (UIElement) this.RootFrame;
}

protected virtual PhoneApplicationFrame CreatePhoneApplicationFrame()
{
return new PhoneApplicationFrame();
}

protected virtual void OnLaunch(object sender, LaunchingEventArgs e)
{
}

protected virtual void OnActivate(object sender, ActivatedEventArgs e)
{
}

protected virtual void OnDeactivate(object sender, DeactivatedEventArgs e)
{
}

protected virtual void OnClose(object sender, ClosingEventArgs e)
{
}
}

So the PhoneBootstrapper abstracted away the original App.xaml.cs and we now just inherit it. If we ever wanted to handle these states therefore, we could just say in our Bootstrapper to override these methods.

Next, what’s the best thing about this is it automatically binds your ViewModel to your Views without having to manually implement dependency injection. Basically, if you have a MainPageView.xaml, and you created a MainPageViewModel then the caliburn micro should automatically inject the ViewModel to the View or from the View to the ViewModel which is normally called as ViewModel First or View First approach.

Next, how do we then bind our ViewModel properties to our View controls? The traditional way would be saying {Binding Path=FirstName}. In caliburn micro you don’t do it that way. You just say <TextBlock x:Name=”FirstName”/> and it will automatically bind the property name FirstName from the ViewModel. All the traditional ways are being abstracted away from us making it simplier to code and develop applications in WPF, Silverlight or Windows Phone 7. This is why the Framework’s slogan is “Convention over configuration”, so you are still doing MVVM but those manually long codes is now handled behind the scenes. It’s just like saying you are a new developer and you don’t know where to start. Most of the people before preferred to code in Visual Basic because its easy to use and most of the common things that have to be code are already handled by the Visual Basic. Same goes with this framework, if you are new to MVVM and would like to develop an application but want to make sure you are following the MVVM Pattern, then this framework is for you.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s