by Per Ökvist - .Net
First, what is Caliburn Micro ? It´s a lightweight MVVM framework, with support for WP7 specific features as TombStoning, Launcher, Choosers, a PhoneContainer for simple IoC and uses naming conventions for binding and events. This gives you a neat framework to get going with your WP7 app development.
The demo project is based on the WP7 Visual Studio template that comes with Caliburn.Micro. To use the templates download the latest build and run the power shell script to get your template zip file. Copy it to your template directory.
In the RTW of the Windows Phone 7 developer tools there are now a pivot control. So I set off to try this out, trying to mimic the scenario of the Inbox filtering.
If you look at the Pivot template that comes with the tools you see that the pivot items are populated with there content data. I was interested in trying to be able to provide that data in a another way, and also check if there was an easy way to apply the filtering in a “Lazy” way.
I used the “deafult” MainPageViewModel, this holds the different Pivots that I want to use. So I bind a collection of filters to the Pivot Control. Caliburn will the display this model with the MainPage.xaml. The property for the collection on the MainPageViewModel is named Items. Using Caliburns conventions, I could now use binding through naming the Pivot control items.
|
1 |
<controls:Pivot x:Name="Items" Title="Pivot Demo"> |
|
1 2 3 4 |
protected override void Configure() { container = new PhoneContainer(); container.RegisterSingelton<MainPageViewModel>("MainPageViewModel"); |
This will bind my Filter Collection (Items) to the Pivot Control. The control should be populated with a PivotItem for each filter. Inside each PivotItem the collection of data should be shown in a list box. I created a PivotFilter class to hold these properties. The filter collection now contain my PivotFilters. This enables me to bind the PivotFilter.Title to the PivotItem header for each filter. Each PivotFilter also contains a collection of its filtered items, to bind to the ListBox.
|
1 2 3 4 5 6 7 8 9 10 |
<controls:Pivot.HeaderTemplate> <DataTemplate> <TextBlock Text="{Binding Title}" /> </DataTemplate> </controls:Pivot.HeaderTemplate> <controls:Pivot.ItemTemplate> <DataTemplate> <ListBox ItemsSource="{Binding Items}" ItemTemplate="{StaticResource SimpleList}" /> </DataTemplate> </controls:Pivot.ItemTemplate> |
Basic bindings are done. To try out some lazy binding I need to be able to filter data each time a Pivot is changed. I found that the LoadingPivotItem event of the Pivot Control might be handy. To be able to lazy filter I also need to the PivotFilter when the event is triggered. Using Caliburn I set this up like this:
|
1 2 3 4 5 6 7 8 9 |
<controls:Pivot x:Name="Items" Title="Pivot Demo"> <i:Interaction.Triggers> <i:EventTrigger EventName="LoadingPivotItem"> <cal:ActionMessage MethodName="Filter"> <cal:Parameter Value="$eventArgs" /> </cal:ActionMessage> </i:EventTrigger> </i:Interaction.Triggers> <controls:Pivot.HeaderTemplate> |
This will call a method on my MainPageViewModel named Filter each time the LoadingPivotItem is triggered. Caliburn also allows me to pass on the original eventargs to my method, so I could reach the item. The cal-functions comes from the CaliBurn framework through;
|
1 |
xmlns:cal="clr-namespace:CaliburnMicroPivotFilter.Framework" |
So now I have a simple foundation, lets refactor and put the PhoneContainer to use.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class FlaggedFilter : PivotFilter<MailItem> { public FlaggedFilter(IDataProvider<MailItem> dataProvider) : base(dataProvider, true) {} public override string Title { get { return "Flagged"; } } protected override Func<MailItem, bool> FilterPredicate { get { return x => x.Flagged; } } } |
|
1 2 3 4 5 |
private set { this.items = value; base.NotifyOfPropertyChange(() => this.Items); } |
|
1 2 3 4 |
container.RegisterSingleton<IDataProvider<MailItem>, DataProvider>(); container.RegisterSingelton<PivotFilter<MailItem>, AllFilter>(); container.RegisterSingelton<PivotFilter<MailItem>, UnreadFilter>(); container.RegisterSingelton<PivotFilter<MailItem>, FlaggedFilter>(); |
When I got the Pivot filtering to work, I started to wonder if it would be easy to add tombstoning support. Running the app in the emulator, filtered, then pressed the windows button on the “phone” the app is closed and the start screen appears. Pushing the back button “Resumes” the app, but when my app resumes I´m back at “All Items” . Why ? I did´t persist the state of my app when the app was tombstoned, and I didn’t resume it from that state.
Caliburn provides a attribute called SurviveTombstone. This gives you a way to Persist and resurrect the state of your model. This is done by a default implementation of ITombstone. So decorating your model with this attribute along with all properties to persist, will persist it to the phone.state.
If you use some other of Caliburn classes like Screen or Conductor this also gives you hooks for Activation and Deactivation among other things. So I used the Conductor class to keep track of my ActiveItem and Persist my SelectedIndex on tombstoning. More information and sample of Conductor and screen can be found in the WP7 documentation on the Caliburn micro site.
My app now supports tomstoning in a simple way, though it refilters the ActiveItem on activation.
Enjoy!
Here is the link;
http://cid-7448e865de2552ab.office.live.com/self.aspx/Public/CaliburnMicroPivotFilter.zip
I´ll update the post.
/P
Interesting post!
I’d definitely love to peek at your source code, hopefully you could fix the download link?
I am interested in how you have used he filtering. Is the source available for download? (the link seems broken
[...] Windows Phone 7 -Pivot Filtering with Caliburn Micro [...]
Thanks for your piece of code snippet.
Oops looks like it filtered out the interesting part. Maybe this will work
cal:Message.Attach=”[Event LoadingPivotItem] = [Action Filter($eventArgs)]“>
Nice article! One quick comment on the action message. If you wanted, you could use the short syntax for that, like so:
[...] This post was mentioned on Twitter by Dag König, Jayway WP7 and Rikard Ottosson, Per Ökvist. Per Ökvist said: Posted about #Caliburn.Micro and WP7 at the #jayway blog. http://bit.ly/97d6rI #wp7dev [...]