A couple of days ago Sébastien Lachance wrote an excellent article about mimicking the application bar of the game hub. Really interesting for one of my applications which makes use of a minimal applicationbar that’s also transparant. However quite often the texts of the menu are difficult to read when they don’t have a solid backgroud. That’s exactly what is solved in the game hub: a transparant applicationbar, but when expanded to view the menu it has a solid background. And Sébastien also found a solution how to fix this in our own applications.
However Sébastien is using the ApplicationBar, I’m using the wrapper around the ApplicationBar, called BindableApplicationBar that’s part of the Phone7.Fx project. So how to solve this?
The ApplicationBar and BindableApplicationBar both implement the IApplicationBar interface which prescribes the StateChanged event that is used by Sébastien in his solution. So it looks like we can use the same event, let’s look a little bit closer…
Seems that the code inside the BindableApplicationBar never fires the StateChanged event, so let’s fix this with a little bit of code in the BindableApplicationBar. Please be aware that you need to use the source version of the BindableApplicationBar to be able to fix this. So let’s subscribe the underlying ApplicationBar first, we do this in t he constructor of the BindableApplicationBar by adding one line.
public BindableApplicationBar()
{
_applicationBar = new Microsoft.Phone.Shell.ApplicationBar();
_applicationBar.StateChanged += HandleStateChanged;
Loaded += BindableApplicationBarLoaded;
}
Now we still need to implement the HandleStateChanged method, which is a pretty straight forward implementation you’ve probably seen thousands of times.
private void HandleStateChanged(object sender, ApplicationBarStateChangedEventArgs e)
{
if (StateChanged != null)
{
StateChanged(this, e);
}
}
So we now have a BindableApplicationBar that has all the features we need to mimic the ApplicationBar of the game hub. The rest of the implementation could be similar to Sébastien’s code. However I thought this is a typical thing that you can easily implement and reuse in a Behavior. I’m not writing behaviors daily, so I thought giving a look at the blog of the Behavior Master himself, Joost van Schaik. About a year ago he wrote a pattern for safe event detachment in behaviors.
So I started with this pattern as a basis. However my eagerness to make this Behavior perfect by immediately using this pattern caused me a lot of trouble. The pattern also tries to safely remove the events when the AssociatedObject aka Control is unloaded. The control I use is of a special type, the BindableApplicationBar, which immediately calls the unloaded event, don’t know why, but it took me almost an hour to find this out. In the end I did a step back and removed the Safe Pattern, and came to the following behavior. The essence is in the highlighted line where I set the BarOpacity property.
public class TransparantToFillApplicationBarBehavior : Behavior<BindableApplicationBar>
{
private double? _originalBarOpacity;
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.StateChanged += StateChanged;
}
private void StateChanged(object sender, ApplicationBarStateChangedEventArgs e)
{
if (!_originalBarOpacity.HasValue)
_originalBarOpacity = AssociatedObject.BarOpacity;
AssociatedObject.BarOpacity = e.IsMenuVisible ? 1 : _originalBarOpacity.Value;
}
protected override void OnDetaching()
{
AssociatedObject.StateChanged -= StateChanged;
base.OnDetaching();
}
}
And now you want to use it in your BindableApplicationBar, of course.
<ApplicationBar:BindableApplicationBar Mode="Minimized"
BarOpacity="0.6"
IsVisible="{Binding LoggedIn}" BackgroundColor="{StaticResource PhoneBackgroundColor}">
<i:Interaction.Behaviors>
<ApplicationBar:TransparantToFillApplicationBarBehavior />
</i:Interaction.Behaviors>
<ApplicationBar:BindableApplicationBarMenuItem Text="about+settings"
Command="{Binding AboutCommand}" />
</ApplicationBar:BindableApplicationBar>
And the end result is like this. Transparent when the menu is collapsed.

And non-transparent when the menu is visible.
