Using commands with ApplicationBarMenuItem and ApplicationBarButton in Windows Phone 7

.NET, MVVM, Phone, Silverlight, Technical stuff, Windows Phone, Work
No Comments

This post was imported from my old blog and had 19 comments which are included as a screenshot at the end of this post.

Unfortunately, in the current version of the Windows Phone 7 Silverlight framework, it is not possible to attach any command on the ApplicationBarMenuItem and ApplicationBarButton controls. These two controls appear in the Application Bar, for example with the following markup:

<phoneNavigation:PhoneApplicationPage.ApplicationBar>
    <shell:ApplicationBar x:Name="MainPageApplicationBar">
        <shell:ApplicationBar.MenuItems>
            <shell:ApplicationBarMenuItem 
                Text="Add City" />
            <shell:ApplicationBarMenuItem 
                Text="Add Country" />
        </shell:ApplicationBar.MenuItems>
        <shell:ApplicationBar.Buttons>
            <shell:ApplicationBarIconButton 
                IconUri="/Resources/appbar.feature.video.rest.png" />
            <shell:ApplicationBarIconButton 
                IconUri="/Resources/appbar.feature.settings.rest.png" />
            <shell:ApplicationBarIconButton 
                IconUri="/Resources/appbar.refresh.rest.png" />
        </shell:ApplicationBar.Buttons>
    </shell:ApplicationBar>
</phoneNavigation:PhoneApplicationPage.ApplicationBar>

This code will create the following UI:


Application bar, collapsed


Application bar, expanded

ApplicationBarItems are not, however, controls. A quick look in MSDN shows the following hierarchy for ApplicationBarMenuItem, for example:

Unfortunately, this prevents all the mechanisms that are normally used to attach a Command (for example a RelayCommand) to a control. For example, the attached behavior present in the class ButtonBaseExtension (from the Silverlight 3 version of the MVVM Light toolkit) can only be attached to a DependencyObject. Similarly, Blend behaviors (such as EventToCommand from the toolkit’s Extras library) needs a FrameworkElement to work.

Using code behind

The alternative is to use code behind. As I said in my MIX10 talk, the MVVM police will not take your family away if you use code behind (this quote was actually suggested to me by Glenn Block); the code behind is there for a reason. In our case, invoking a command in the ViewModel requires the following code:

In MainPage.xaml:

<shell:ApplicationBarMenuItem Text="My Menu 1"
    Click="ApplicationBarMenuItemClick"/>

In MainPage.xaml.cs

private void ApplicationBarMenuItemClick(
    object sender, 
    System.EventArgs e)
{
    var vm = DataContext as MainViewModel;
    if (vm != null)
    {
        vm.MyCommand.Execute(null);
    }
}

Conclusion

Resorting to code behind to bridge the gap between the View and the ViewModel is less elegant than using attached behaviors, either through an attached property or through a Blend behavior. It does, however, work fine. I don’t have any information if future changes in the Windows Phone 7 Application Bar API will make this easier. In the mean time, I would recommend using code behind instead.

GalaSoft Laurent Bugnion
Laurent Bugnion (GalaSoft)

Share on Facebook

This post was imported from my old blog. Original comments screenshot: 12-11-2013 9-02-50 PM

Leave a Reply