Welcome back :)
After wasting spending a couple weeks writing the "sprint two" post on data entry (and MVVM, DI, etc), I've realised that I need to focus on audience. Sean d'Souza and The Brain Audit have finally sunk in.
When I started this series of posts, I didn't really consider who exactly I was writing for. Trying to balance between beginner and intermediate is tough, especially when I'm fairly new to WP8 development. Someone is bound to get bored or lost.
So I've made a decision.
These posts are targeted at experienced Windows developers, preferably with some knowledge of WPF and MVVM, who want to write a Windows Phone 8 app.
Of course this means the series has officially been renamed to "Journey to the WP8 App Store in 3 months" :) Eep!
I'm going to be using Matteo Pagani's series on Caliburn Micro with Windows Phone 8 as a reference (along with SO, of course). In case Matteo's site disappears, I'm copying the code examples here and modifying as required to work with the latest version of Caliburn.Micro. Total credit goes to Matteo.
Moving to Caliburn.Micro
I come from a heavy Prism background, so seeing the PhoneBootstrapper
class made my eyes light up. (On a side note, I don't see p&p paying any attention to Prism for WP8 which is why I had to choose between MVVM Light and Caliburn.Micro)
To be honest, this looks an awful lot like configuring Prism. Unity
has been replaced with PhoneContainer
and there a few phone-specific methods, but the code should be quite recognizable.
Create a Bootstrapper
public class Bootstrapper : PhoneBootstrapper
{
PhoneContainer container;
protected override void Configure()
{
// Fixes a superfluous compiler error while viewing App.xaml
// Value cannot be null. Parameter name: rootFrame
if (Execute.InDesignMode)
{
return;
}
container = new PhoneContainer();
container.RegisterPhoneServices(RootFrame);
container.PerRequest<MainViewModel>();
AddCustomConventions();
}
static void AddCustomConventions()
{
}
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);
}
}
Update (clean up) App
We declare the bootstrapper inside Application.Resources
, and since we're letting the framework configure everything for us, we can strip these files down to a minimum.
<Application
x:Class="IsItWorthIt.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:IsItWorthIt">
<Application.Resources>
<local:Bootstrapper x:Key="Bootstrapper"/>
</Application.Resources>
</Application>
and the code-behind
public partial class App : Application
{
public static PhoneApplicationFrame RootFrame { get; private set; }
public App()
{
// Standard XAML initialization
InitializeComponent();
// Show graphics profiling information while debugging.
if (Debugger.IsAttached)
{
// Display the current frame rate counters.
Application.Current.Host.Settings.EnableFrameRateCounter = true;
// Prevent the screen from turning off while under the debugger by disabling
// the application's idle detection.
// Caution:- Use this under debug mode only. Application that disables user idle detection will continue to run
// and consume battery power when the user is not using the phone.
PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
}
}
}
Displaying our view
Since our application comes with a built-in sample view and viewmodel, let's connect them first. Caliburn.Micro seems to rely on convention over configuration which means a couple things for us:
- Views and ViewModels are stored in separate folders, named
Views
andViewModels
. Note that the sample app already createsViewModels
for you. - The namespaces for Views and ViewModels should also end in
Views
andViewModels
. - A View and ViewModel are linked by name (e.g.
Items
<->ItemsViewModel
)
To update the demo app,
- Create a
Views
subdirectory at the same level asViewModels
- Move
MainPage.xaml
toViews
- Update its namespace (remember to update the full class name in
.xaml
as well. You'll also need to update the path to the SampleData folder by prepending../
) - Delete the code in the constructor that's setting the
DataContext
(Caliburn.Micro is doing this automagically for us now) - Delete the entire
OnNavigatedTo
method - Delete the line in
DetailsPage.OnNavigatedTo
that is setting theDataContext
. Details will just have to be broken for now. - Rename
MainViewModel
toMainPageViewModel
- Add a call to
LoadData
from theMainPageViewModel
constructor. - Double-click on
Properties/WMAppManifest.xml
and update the Navigation Page toViews/MainPage.xaml
After performing the appropriate steps to get the sample MainPage
view and viewmodel configured appropriately, you should be able to run the application and see....exactly what you would have seen before we introduced Caliburn.Micro :)
Interested in learning more about developing for Windows Phone 8? Enter your information to receive e-mail notifications on relevant articles.
Comments