Interested in what's coming up? Take a look at the Roadmap!
To get started quickly, add references to the Liphofra assemblies in your Windows Phone project. Then, in the application class constructor, initialize the bootstrapper, like:
// initialize Liphofra
Bootstrapper.Initialize(RootFrame);
The "Bootstrapper" type is located in the namespace "Liphofra.Mvvm". Important: because it relies on the root phone application frame this initialization call obviously must be done after the "InitializePhoneApplication" call of the default Windows Phone template, so "RootFrame" is initalized properly.
What the bootstrapper does:
After that, you can use all the features of Liphofra using the provided default implementations. You can override any of these (including the service locator itself) by doing the registrations manually.
To prepare your pages for special Liphofra features, do the following:
1.) After creating a default phone application page from the Visual Studio templates, change the base type in the code-behind class to "Liphofra.Mvvm.Views.PhoneApplicationPage"
2.) Change the type in Xaml also. To this end, you need to add a namespace definition for the corresponding Liphofra namespace:
<liphofra:PhoneApplicationPagexmlns:liphofra="clr-namespace:Liphofra.Mvvm.Views;assembly=Liphofra.Mvvm" /><!-- ... -->
</liphofra:PhoneApplicationPage>
As a convenience, the page offers the following protected properties:
In addition to the normal overridable protected methods of a "PhoneApplicationPage", the Liphofra implementation also differentiates a bit more between scenarios like "the user returned to the page from tombstoning" or "the user returned to the page, but it wasn't tombstoned". This spares you writing the same boilerplate code again and again. In particular, the following overridables are available:
More methods available on the phone application page implementation:
The page implements some helper functionality behind the scenes. For example, when the user is about to navigate away from the page, it checks the currently focused UI element and updates its binding expression, if applicable. This makes sure that e.g. text box bindings are updated correctly and the actual value of these controls is reflected in the view model layer when the navigation notifications are raised.
The next step is to prepare your view model for the just created page.
Your page view models should derive from "Liphofra.Mvvm.ViewModels.NavigationViewModelBase". This base type provides the following convenience properties:
If you don't change the default bootstrapping mechanism, these properties will contain the default Liphofra implementations of these interfaces.
The view model also supports the same new extension points as the corresponding page implementation, as overridable protected methods:
In addition, as a convenience the normal page overrides are invoked on the view model also:
The view model implementation of course also supports INotifyPropertyChanged (using the "OnPropertyChanged" base method) and has a default implementation of "IDisposable" that is automatically invoked
To bring together pages and their corresponding view models, so-called view model locators are used. Liphofra favors one-to-one relationships between views and view models, meaning that there typically are no singleton instances or similar constructs for view models, as you may be used to in other frameworks. This has some design implications for your application, for example it usually forces you to store state and data in lower layers ("business logic") rather than using the view models for that.
Liphofra has a dynamic view model locator implementation that makes it simple to set up and use this mechanism for most cases. Here is what needs to be done:
1.) In your application resources, add an entry that creates a dynamic view model locator, like:
<Application.Resources><liphofra:DynamicViewModelLocator x:Key="DynamicViewModelLocator" /></Application.Resources>
2.) In your pages, set the data context using that view model locator:
<liphofra:PhoneApplicationPageDataContext="{Binding [MyViewModel], Source={StaticResource DynamicViewModelLocator}}" />
Please note the square brackets around the view model type name – these are important and required due to a limitation of C#'s dynamic features on the phone. What this does is:
The default implementation of th factory uses the configured IoC container to resolve the view model instance (so you could actually also do a singleton view model approach if you registered a view model instance as singleton) and configures its properties if the resolved type is an "INavigationViewModel" instance.
Liphofra also supports custom view model locators for each and every view and view model pair, if you want to do that. To this end, an abstract "ViewModelLocatorBase" type exists that provides properties for both design-time and runtime view models. You would typically derive from this locator to define the view model types to use for a view explicitly.
A convenience derived type from this base locator also exists, which only takes one generic type parameter. This implementation provides the identical types for both design-time and runtime.
Liphofra has more features than the above mentioned ones. In particular: