-
First steps with Caliburn Micro in Windows Phone 8 – The theory
If you’re a Windows Phone developer you’ll probably have heard of Model-View-ViewModel (MVVM for friends): it’s the most widely approach used for development with technologies based on XAML, like WPF, Silverlight and, more recently, Windows Phone and Windows Store apps. I won’t go deep about MVVM in this post, this is not its purpose and probably it would require 10 or 15 posts to cover all the aspects.**
Let’s just say that it’s a way to split your code into three main concepts, in order to separate the layers that are responsible of managing the data of your application from the one that are responsible to interact with the user interface.
I’ve always been a huge fan of the MVVM Light toolkit by Laurent Bugnion, but I’m also a curious developer so I started to give it a try to another famous MVVM toolkit, which is Caliburn Micro. Why am I talking about toolkits and not libraries? Because MVVM is a pattern, that is a way to define the architecture of an application. For this reason, these toolkits don’t implement MVVM, but they offer a set of helpers and utilities to help the developer in implementing the pattern.
MVVM Light and Caliburn.Micro have two different approaches. Let’s see pros and cons.
MVVM Light
MVVM Light is very lightweight and simple and leaves the developer in control of everything. For this reason, the infrastructure provided by the toolkit is very simple. Basically, it offers some helpers to implement the basic requirements of a MVVM application, like:
- A class, from which a ViewModel can inherit, in order to provide basic functionalities like INotifyPropertyChanged support
- A command implementation, to manage operations that are executed when a user interacts with a control
- A messenger implementation, in order to exchange messages between different view models or between a view model and a view
- A built in simple dependency injection container, to automatically resolve view models and their dependencies
Which are the pros of using MVVM Light? Since its implementation is very simple, it gives a lot of power to the developer to customize it and to adapt the MVVM architecture to fit its needs. Plus, since MVVM Light uses the standard concepts that should be familiar to every XAML developer, like binding and the INotifyPropertyChanged implementation, it’s very simple to understand for other developers that need to work on your project.
The cons is basically just one: since the implementation is very simple, the developer has to do a lot of work to implement everything and to manage correctly scenarios that are very common in a Windows Phone application, like tombstoning or navigation, but that are hard to manage in a MVVM application due to the separation between the view and the view model.
Caliburn Micro
Caliburn Micro, on the other side, has a more complex configuration than MVVM Light, that allows the developer to be more productive and to hide all the mechanism that under the hood are used to implement the MVVM pattern.
Caliburn Micro is heavily based on conventions to connect the different part of the application: for example, you don’t have to use a ViewModelLocator class to dispatch the view models, because it’s enough to give to a model the same name of the view plus the ViewModel suffix (for example, MainView and MainViewModel) to connect the two of them and have the ViewModel automatically bound with the DataContext of the view.
Or, for example, you just have to give to a control (for example, a TextBlock) the same name of a property defined in the ViewModel to connect the two of them in binding, so that if the property changes also the control is refreshed to display the updated value.
Which are the pros of using Caliburn Micro? The most important one is that most of the overhead that you have to add in your application to support MVVM is hidden by the toolkit. This approach minimizes the efforts needed for the developer, that usually needs to do many repetitive steps every time he needs to start a new project and to configure the environment. Plus, Caliburn Micro comes with many helpers to specifically resolve common Windows Phone scenarios, like managing the tombstone, interacting with the application lifecycle or using launchers.
The cons are that, in my opinion, the initial setup is a bit more complex than in MVVM Light, due to the infrastructure needed to support all the features. Plus, being heavily based on conventions is very helpful for the developer, but makes the project hard to understand for people that don’t know Caliburn Micro and that can’t understand all the operations that are made under the hood without an explanation. Just to make an example, since there isn’t a ViewModelLocator or a central dispatcher of the view models, it’s almost impossible to understand how Views and ViewModels are connected together if you don’t know the naming convention I’ve explained you before. However, one nice thing about Caliburn Micro is that it supports conventions, but you don’t have to use them if you don’t want: as we’ll see in the next posts, exactly like with every other MVVM toolkit, since the ViewModel is the DataContext of a View, so you can also use standard bindings to connect things together.
The practice… coming soon
In the next post we’ll start to make some practice and we’ll start to set up a Windows Phone project that uses Caliburn Micro. Stay tuned!
The Caliburn Micro posts series
in
-
How to save a picture captured with the new camera’s API in the camera roll in Windows Phone 8
Windows Phone 8 has introduced new APIs to interact with the native camera and to take pictures and record videos. These APIs are much more powerful than the ones that are available in Windows Phone 7: you have full control over all the camera settings, like exposure, focus, flash and so on.
There’s a good example in the MSDN documentation about how to use them: unlucky the article has some minor issues, so you can face some problems. Let’s see, in details, how to use the new APIs and how to apply a workaround to fix these issues.
Usually the first goal you want to achieve when you develop a camera application is to display the camera’s stream in your application: for this purpose we’re going to use a VideoBrush, which is one of the available brush in XAML that can be used to customize a control.
We’re going to insert a VideoBrush inside a Canvas, to display the camera’s stream inside it:
<Canvas Height="400" Width="400"> <Canvas.Background> <VideoBrush x:Name="video" Stretch="UniformToFill"> <VideoBrush.RelativeTransform> <CompositeTransform x:Name="previewTransform" CenterX=".5" CenterY=".5" /> </VideoBrush.RelativeTransform> </VideoBrush> </Canvas.Background> </Canvas>
You can notice that we apply also a CompositeTransform to the brush: as we’ll see soon, this is needed to rotate the stream according to the phone’s rotation.
Now we need to get access to the camera in our code: we’re going to use the new class PhotoCaptureDevice, that has replaced the PhotoCamera class that was available in Windows Phone 7. The old class is still there but, if you don’t need to keep the compatibility with both platforms, I suggest you to use the new one, since it’s much more powerful.
We’re going to initialize the camera in the OnNavigatedTo event:
public partial class MainPage : PhoneApplicationPage { public MainPage() { InitializeComponent(); } private PhotoCaptureDevice camera; protected override async void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); Size resolution = PhotoCaptureDevice.GetAvailableCaptureResolutions(CameraSensorLocation.Back).First(); camera = await PhotoCaptureDevice.OpenAsync(CameraSensorLocation.Back, resolution); video.SetSource(camera); previewTransform.Rotation = camera.SensorRotationInDegrees; } }
The first step is to define which is the resolution we’re going to use to take our photos: for this reason we use the GetAvailableCaptureResolutions() method of the PhotoCaptureDevice class, passing as parameter which camera we want to use: CameraSensorLocation.Back for the rear camera and CameraSensorLocation.Front for the front camera. The method returns a list of all the supported resolutions by the camera, starting from the highest to the lowest. In our example we take the picture using the maximum available resolution, so we take just the first of the list and we pass it, as parameter, to the OpenAsync method of the PhotoCaptureDevice class, together (again) with the camera we want to use. We use the await keyword (and, as a consequence, we mark the OnNavigatedTo method with the async keyword) since it’s asynchronous.
The last step is to display the camera’s stream on the screen, by passing the PhotoCaptureDevice object to the SetSource method of the VideoBrush. We also set the rotation of the transformation applied to the brush according to the rotation of the camera, using the SensorRotationInDegrees property.
Important! Notice that, to do this operation, we need to add in our class the namespace Microsoft.Device: this is required to set the PhotoCaptureDevice object as a source for the VideoBrush, since it adds an override of the SetSource method that accepts as parameter an ICameraCaptureDevice object, that is the base interface from which every new camera API inherits from.
If you just launch the application you’ll see the image recorded by the camera on the screen: if you test the application on the emulator, it will be generated a fake stream, since the emulator isn’t able to use the computer’s webcam.
Take the picture
The new Windows Phone 8 APIs have introduced the concept of “sequence of frames”, which is a set of pictures taken at the same time. In the current version the frames are limited to 1, so you can capture sequences composed by just one picture.
Here is a sample code that takes the picture and saves it into the camera roll of the phone:
private async void OnTakePhotoClicked(object sender, RoutedEventArgs e) { CameraCaptureSequence cameraCaptureSequence = camera.CreateCaptureSequence(1); MemoryStream stream = new MemoryStream(); cameraCaptureSequence.Frames[0].CaptureStream = stream.AsOutputStream(); await camera.PrepareCaptureSequenceAsync(cameraCaptureSequence); await cameraCaptureSequence.StartCaptureAsync(); stream.Seek(0, SeekOrigin.Begin); MediaLibrary library = new MediaLibrary(); library.SavePictureToCameraRoll("picture", stream); }
First we create a new CameraCaptureSequence object, by using the CreateCaptureSequence method of the PhotoCaptureDevice object. As parameter we need to pass the number of frames to capture: as I’ve just explained, due to a limit in the current APIs, we have to pass 1 as value; other values are not supported.
Then we create a new MemoryStream object, that will hold in memory the photo captured by the camera: we connect the output of the stream to output of the first frame of the sequence, that is the photo that will be captured. We do this by using the CaptureStream property of the first stream, that is available in the Frames collection of the sequence.
In the end, we take the picture: first we prepare the sequence (by calling the PrepareCaptureSequenceAsync method of the PhotoCaptureDevice object) an then we call the StartCatureAsync method on the sequence. Both methods are asynchronous, so we use the await keyword.
Now that we have the picture, we save it in the phone media library: and here is where need to apply a workaround, that is not mentioned in the MSDN article. We need to set the stream’s position of the MemoryStream object to the beginning, otherwise you’ll get a cryptic InvalidOperationException error with the An unexpected error has occured message, that isn’t helpful. The credit to this workaround goes to Marco Leoncini, a dear friend of mine and a member of the ASPItalia crew, that has helped me to understand why the sample provided in the MSDN article didn’t work.
We have two options to save the picture in the library: in the sample we use the SavePictureToCameraRoll method of the MediaLibrary object to save the picture in the camera roll. We have also another method, SavePicture, that can be used to save the image in the Saved pictues folder of the media library. It’s up to you choosing which is the best for your needs: if you’re developing a camera-replacement application (for example, a Lens app) probably you would prefer to save it in the camera roll, to be consistent with the experience provided by the native application.
Happy coding!
P.S. I would like to thank you also Lance Mc Carthy, a Nokia ambassador that helped me to track the issue and that it’s been very kind to quickly reply to my questions on Twitter.
in
-
Lex.db: a new database storage solution for Windows Phone 8
Recently, on my blog, I’ve talked a lot about the database solutions that are available in Windows Phone 8. There are many different ways to manage database, each one with its pros and cons. SQL CE with LINQ to SQL is the most powerful one, but isn’t supported by Windows 8 and it’s hard to share the code and the database with other platforms. SQLite support is very promising and the engine is very fast, but at the moment it lacks a powerful library to manage data, so it’s a bit limited.
Please welcome a new participant in this “contest”: Lex.db, an interesting solution developed by Lex Lavnikov (pay often a visit to his blog because it regularly posts update about the project). Do you remember Sterling? It’s an object oriented database that uses the file system to store data in a structured way, so that it can be used with LINQ to do queries and operation like a regular database. The biggest pro is that is available for many .NET technologies and it’s very fast, especially if you simply need to persist data: since it uses just the file system, it doesn’t add the overhead of a database engine.
Lex.db is based on the same principles, but it supports also Windows Runtime: for this reason it can be used not only with Windows Phone 8, but also with Windows Store apps and with the full .NET framework. How does it work? Lex.db is able to automatically serialize the data that we need to store in the file system and to keep in memory just the keys and the indexes that are needed to perform operations on the file. For this reason it’s really fast and often performances are superior than using SQL Lite.
Which are the downsides? For the moment, it still doesn’t support Windows Phone 7, so it’s not the perfect choice if you need to share the data layer of your application between two projects for Windows Phone 7 and Windows Phone 8. Plus, it’s not a real database solution: for example, for the moment relationships are not supported, so you’ll have to manually manage them if you need.
But, for example, if you’re going to develop a To Do List app (or any other app that needs to hold in storage a collection of data) and you want to share the data layer with a Windows Store version of the app it’s a really good solution.
Let’s see how to use it in a Windows Phone application (but the code would be exactly the same for a Windows Store app).
The first setup
The simplest way to use Lex.Db in your project is to install it using NuGet: right click on your project, choose Manage NuGet packages and, using the built in search engine, look for and install the package called Lex.db.
After that we can create the entity that will hold the information that will be stored in the file system. Unlike with sqlite-net or LINQ to SQL, we don’t have to decorate classes with special attributes: we just need to define the class. Let’s use the ToDo List app example: in this case we need a class to store all the information about an activity.
public class Activity { public int Id { get; set; } public string Title { get; set; } public string Description { get; set; } public DateTime ExpireDate { get; set; } }
Now, exactly like we do with SQL CE or SQL Lite, we need to tell to the library which is the structure of our database. In our example we’ll have one “table” to store all the activities. First we declare a new DbIstance object in the page, so that can be used by every method of the class:
private DbInstance db; private async void LoadDatabase() { db = new DbInstance("catalog"); db.Map<Activity>() .Automap(x => x.Id); await db.InitializeAsync(); }
Then we create a new instance of the DbInstance class, passing as parameter the name of the folder that will be created in the local storage to store all the data. We’ll need to refer always to this key in order to do operations on our data.
Then, using a fluent approach, we set which is the entity that we need to store with the **Map
** method, where T is the class we’re going to serialize (in our example, **Activity**). In the end we define which is the primary key of the table, that will be used to perform all the queries, using the **Automap** method: by using the lambda syntax we specify which property of our entity is the primary key, in our example the **Id** property. Before moving with doing operations we call the **InitializeAsync()** method on the **DbInstance** object, so that the library is able to create all the needed infrastructure to store the data. It’s an asynchronous operation, so we mark the method with the **async** keyword and we use the **await** keyword in order to wait that everything is correctly setup before doing something else. The library provides also synchronous methods, but I always suggest you to use the asynchronous ones, in order to provide a better user experience. Now we are ready to save some data:
private async void OnInsertDataClicked(object sender, RoutedEventArgs e) { Activity activity = new Activity { Id = 1, Title = "Activity", Description = "This is an activity", ExpireDate = DateTime.Now.AddDays(3) }; await db.Table<Activity>().SaveAsync(activity); }
The syntax is pretty straightforward: we create a new Activity object and we pass it to the SaveAsync method on the **Table
** object, which is the mapping with the “table” that stores our data. Simple, isn’t it? And if we want to get our data back? Here is an example: private async void OnReadDataClicked(object sender, RoutedEventArgs e) { Activity[] activities = await db.Table<Activity>().LoadAllAsync(); foreach (var activity in activities) { MessageBox.Show(activity.Title); } }
In this sample we retrieve, using an asynchronous method, all the Activity entities with the LoadAllAsync method, that is available using the **Table
** property of the database. Since the primary key of the table acts also as index, we can also query the table to get only the item with a specific id, by using the **LoadByKeyAsync** method: private async void OnReadDataClicked(object sender, RoutedEventArgs e) { Activity activity = await db.Table<Activity>().LoadByKeyAsync(1); MessageBox.Show(activity.Title); }
Please note! The DbInstance object exposes directly some methods to do these basics operations, like Save() and LoadAll(). The library is able to understand which class we are using and to do the operation on the correct table. Anyway, I suggest you to always access to the data using the **Table
** property because, this way, you have access also to the asynchronous method that, otherwise, wouldn’t be available. Using indexes
One common scenario in such an application is to query the data, to get only the items that meet specific criteria. This is what index are for: during the database setup you can choose to use one or more properties as index and use them to perform query operations. Let’s see an example: let’s say that we want to perform queries on the Title properties, to search for activities with a specific word in the title.
First we need to change the first database configuration:
private async void LoadDatabase() { db = new DbInstance("catalog"); db.Map<Activity>() .Automap(x => x.Id) .WithIndex("Title", x => x.Title); await db.InitializeAsync(); }
We’ve called a new method, which name is WithIndex: as parameter we pass the name of our index (Title, in our case) and, using a lambda expression, which is the property of our entity that will be mapped with the key.
Now we can execute queries on the Title property by using the same LoadAllAsync method we’ve seen before:
private async void OnReadDataClicked(object sender, RoutedEventArgs e) { List<Activity> activities = await db.Table<Activity>().LoadAllAsync("Title", "Activity"); foreach (var activity in activities) { MessageBox.Show(activity.Description); } }
The difference with the previous sample is that now are passing two parameters to the LoadAllAsync() method: the first one is the name of the index to use, while the second one is the value we’re looking for. The result of this code is that the activities collection will contain all the items which Title property is equal to “Activity”.
What’s going on under the hood?
If we want to see what’s happening under the hood we can use a tool like Windows Phone Power Tools to explore the storage of our application. We’ll see that the library has created a folder called Lex.db. Inside it you’ll find a subfolder with the name of the database you have specified when you created the first DbIstance object: inside it you’ll find a .data file, which holds the real data, and a .key file, which is used for indexing. If you try open it with a text editor like Notepad you’ll see the content of the data you’ve stored in the application, plus some other special chars due to the encoding made by the serialization engine of the library.
If you want to experiment a bit with Lex.Db, use the following link to download a sample project I’ve created.
in
subscribe via RSS