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.