Bindable Application Bar (Blend Behavior) – Windows Phone 7

UPDATE 2/22/2012: After fighting with this for over a week and wasting more hours than I thought possible I made a discovery about Blend Behaviors. It seems that Blend Behaviors have a static lifetime. They attach and detach to objects as they come and go, but the instance seems to be static. I discovered this when the value of my Dependency Property was being reused by all instances. Not to mention I made the mistake of newing up a collection as the default for my Dependency Property, thus creating an undesired singleton. After all has been said and done. I switched over to an Attached Property approach. This approach has worked like a charm. You can read about and get the sample code for the new approach here.

Many have claimed to have created a bindable ApplicationBar for the lacking Windows Phone 7 OS. After hours of searching for one that would fit my needs I discovered that they are all lacking or not implemented in a way that was sufficient for my needs. I set out to create my own implementation with the help of Tim Askins and Travis Schilling. What we came up with was not an ApplicationBar replacement or derivative, but a new behavior that can be added to any page in XAML. Note this is NOT an attached behavior. We are inheriting from Behavior<T>.

Why a behavior?

Behaviors have no UI. If we were to use any kind of Control derivative the created control would allow placement anywhere in the UI tree. It would need to do extra work to traverse the tree and find the page as well. This also means that it could potentially be part of a UI tree that was invalid. This concept did not make sense to us. By using a Behavior we force the developer to place the behavior as a first class citizen of any page, and it is restricted to PhoneApplicationPage, but would work with derived pages as well. The behavior is also not part of the UI tree.

Any problems with using a behavior?

The behavior is designed with a collection of ApplicationBarIconButtonDelegate objects. These objects expose many of the same dependency properties which a normal button would expose such as IsEnabled, Command and CommandParameter. They also expose an IsVisible and an IconUri property. However, when these objects are being bound to in XAML they live inside of the behavior. This seem like a no brainer, one just needs to remember that means there is no DataContext to pass around. This was easily overcome by setting the page’s DataContext as the DataContext of each button in the override of the OnAttach method. Once this was done each button delegate was able to bind as expected. In the current implementation we do not handle the case where a page does not have a DataContext, however this would be easily overcome by adding an optional DataContext DependencyProperty to the behavior.

Where’s the code?

After testing the code a bit more I will post up what we have created. Assuming all goes well that will be next Wednesday or sooner.

Win Live Helper for Windows Phone 7

Today I’m proud to announce the home of WinLiveHelper on codeplex. The purpose of this library is to provide lightweight objects and the http calls required to easily interact with the Windows Live SDK that was released 7 Dec 2011. I will be starting with Calendaring and then moving to Documents. After that we’ll see what priorities come up. If you’d like to help out let me know!

Windows Phone 7 – Windows Live SDK

UPDATE 2/22/2012: As mentioned under the section Thoughts I have created a Codeplex project called WinLiveHelper. You can read more about it in this post.

Talk about good mojo! 7 days ago I was I was researching how to access Windows Live and SkyDrive from my Windows Phone 7. It just so happened to be the release date of the brand new Windows Live SDK that day, 7 Dec 2011. I now get the privilege to blog about my discoveries. Most of what I found is really good stuff. I’m going to let Microsoft do the heavy lifting on this one since their samples are quite good.

What is the Windows Live SDK?

The Windows Live SDK is a brand new SDK that encapsulates OAuth2 calls and the building of HTTP requests for Windows Live services. The SDK is very light and does not include model objects for calendars, files, etc. Microsoft has provided us with a Live Interactive SDK that walks through some of the available calls and allows the user to experiment with the JSON used.

What can I Access?

The documentation of what is available via the SDK is very comprehensive. The REST API is the one that I looked at. I’d feel like a member of the Redundant Department of Redundancy listing all of the capabilities of the API, so I’ll only mention a few: Albums, Audio, Calendars, Contacts, Folders, Files, Photos, and Videos. OK, so that’s most of them, but I’ll only talk about a few in specifics here.

Calendar

The Calendar portion of the API allows the developer to access all of the Calendars that the user has referenced in Windows Live. The developer can create, read, update, and delete a calendar. The developer can also create, read, update, and delete events on any of the calendars based on that user’s permissions on that calendar. This is a welcome API on the phone since developers can only read calendars and events in the current version of the OS.

SkyDrive (Folders and Files)

The same create, read, update, and delete capabilities that exist for calendars and contacts also exist now for SkyDrive. What I’m still working on is how to use SkyDrive to open a document on the phone from inside of a third-party application (not the Office Hub). Currently the phone only supports a Photo Chooser which cannot view Videos. I have a need to attach Videos and Files to a piece of information, and with the release of the Windows Live SDK developers can now access any uploaded file (video, audio, document, spreadsheet, etc.) that lives SkyDrive.

Thoughts

I’m hoping to create a light library of model objects that will work with JSON.NET for the phone that I’ll be able to pair with the Windows Live SDK. I’m very excited about the simplicity of the APIs and SDK. I’ve heard the horror stories of integrating Windows Live into an application prior to this SDK and set of APIs.

Windows Phone 7 – Tombstoning

I looked all over the internet to find a good solid article on Tombstoning in Wp7, however it seemed like everyone had a different perspective and each came up a little short of what I wanted. The biggest problem is defining what Tombstoning really is. So lets begin with that.

Definition:

Tombstoning – Using the Deactivation event for the application in order to save state that will be restored during the Activation event.

It’s as simple as that. Now how can we save state? There are a few options to accomplish this.

Local Database (Persistent)

Working with Paul Rohde and Travis Schilling we created an application that utilized the local database for our application. It was pretty nice. It’s completely accessed by LINQ to SQL as far as we can tell. Travis was the man behind all of that work, and he seemed to say it wasn’t difficult once you understand how the DB is created.

IsolatedStorage (Persistent)

In Isolated Storage you have the option to save key-value paired rich objects in IsolatedStorageSettings.ApplicationSettings. This dictionary has a TryGetValue<T>(string name) method that is very useful. This makes for very quick saves of complex object graphs. There is also the option to save files using IsolatedStorageFile and IsolatedStorageFile. I have not used these, but they seem straight forward enough. Microsoft, however does not suggest using any IsolatedStorage options when trying to Tombstone. Why? It’s slower than the alternative PhoneApplicationService.Current.State dictionary.

PhoneApplicationService (Transient)

The PhoneApplicationService is the preferred way to Tombstone your application according to a post from Microsoft. It’s faster than any kind of persistent storage according to that post. You would use PhoneApplicationService.Current.State to add and read transient data. The downside to this dictionary is that the TryGetValue method is not generic by default. We’ll have to create an extension method to have it work the same as IsolatedStorageSettings’ TryGetValue<T>().

What data do I save?

This question, I think, used to be more cut and dry. I remember creating an application pre-Mango (7.5) and if you left the application then went back to the application no data would be persisted because the application was closed not Tombstoned. However I’m seeing that in Mango the current page being viewed when the application is deactivated is not reliably lost. A strange statement, however true. When I deactivate my application I’d expect the VisualTree and object graph to be lost, thus requiring me to save all of the required data during the Deactivated event so it could be restored during the Activation event. I’m not experiencing this. I’m seeing the object graph being kept around as well as associated VMs. Do I need to save this data since I can see it’s not being lost? After talking with Tim Askins we’ve decided it’s best to save the data even if we don’t need to restore it. The saying, “Better safe than sorry” comes to mind.

Best Practices and Cautions

  • Save all data that can be treated as Session data in PhoneApplicationService and store all permanent data in your preferred form of persistent storage (Database or IsolatedStorage).
  • Don’t try to call any web services that would normally be used to store the data if the application continued to run. If data needs to be sent to a web service, enable your application with a background task.
  • Remember you only have 10 SECONDS MAX to be fully Tombstoned before the OS will close your app.
  • Note that you should make sure all of your objects being stored in PhoneApplicationService or IsolatedStorage are marked as DataContract and each property is a DataMember. We also saw this was not really enforced, but I think it’s best practice to do this. Again, “Better safe than sorry.” Plus, Microsoft says that it is required.
  • Save persistent data as it’s changed rather than waiting for the application to be deactivated.

Launching/Closing vs. Activating/Deactivating

The Launching and Closing events should be used to load and save persistent data. Activating and Deactivating events should be used to load and save persistent and transient data. The less persistent data you must handle during Activation and Deactivation the better. Persistent storage is slower than transient storage and therefore reduces the user experience.

Special Thanks

After scoping out the web I’ve found the following links very helpful. Each have different perspectives and insights that I think are worth mentioning as part of the great whole called Tombstoning.

Timers and Alarms in Windows Phone 7.5 (Mango)

One thing I really wish Microsoft had built into the Windows Phone 7 from the beginning was a simple timer. The iPhone has one. The Android has one. Windows Phone 7.5 still has yet to add this simple functionality. So I took the task upon my self to develop one. The first thing I didn’t understand was which Scheduler was the correct Scheduler to use. There were a lot introduced with Wp7.5 found here. Before I even looked at that page I opened up Visual Studio and found the “Windows Phone Scheduled Task Agent” project template and started to play with that. My immediate thought was “PeriodicTask is for scheduling when a timer should run.” This is definitely not the case since PeriodicTasks only run once every 30 minutes or so. Once I discovered Alarm notifications it was very simple to sort all of that out.

The Wp7.5 SDK provides a lot of great controls. However, I found it lacking a way to specify hours, minutes, and seconds through a picker. Luckily Coding4Fun took care of that for me with the TimeSpanPicker. Armed with an Alarm and the TimeSpanPicker I was able to create a super simple timer application.

A few notes about the outcome of the application:

  1. It is not possible to reuse sounds built into the Phone for your custom timer. I still don’t understand why Microsoft will not allow this. Why can’t I have my alarm play one of the built in sounds let alone why can’t I have it play my favorite song when the alarm finishes?
  2. I’ve found that the alarm is accurate up to 30 seconds. Meaning, I found that the alarm notification would not actually notify me right away. The longest delay I’ve found is 30 seconds, but usually it’s within 10 seconds. This is acceptable, but again disappointing.
  3. Sometimes the alarm notification will not display if the application that created it is running. Perhaps this is by design? One could assume that if the application is setting an alarm that it doesn’t intend on running when it completes, and if it is running then it should be tracking the time on its own.