Disabling a button on Windows Phone Application Bar

Standard

Building an application for Windows Phone 8 using XAML allows you to create an Application Bar with buttons and menu items. To define this Application Bar you can either hand code the XAML or Build up the Application Bar through the properties explorer. Either way you end with XAML code similar to this.

    <phone:PhoneApplicationPage.ApplicationBar>
        <shell:ApplicationBar>
            <shell:ApplicationBarIconButton 
		IconUri="/Assets/AppBar/check.png" 
		IsEnabled="True" Text="Okay"/>
        </shell:ApplicationBar>
    </phone:PhoneApplicationPage.ApplicationBar>

This is very simple and easy to use. The only problem with this Application Bar is that it is not bindable to Commands when you use the MVVM pattern. You can handle the tap/click events of the buttons from the Application Bar in the code behind file of your view, but this feels so against the idea of the ViewModel doing the work.

Hosted on CodePlex is the BindableApplicationBar project that was originally created for Windows Phone 7. I’ve added this library to my Windows Phone 8 project via the nuget package and it works. There is a minor issue where the error “Cannot clear the Icon while in a list” is displayed while in the XAML designed. This is not a blocking issue and does not stop your application from compiling or executing. You can gladly ignore the error.

I prefer to use the MVVM Light toolkit for binding my views and viewmodels together. Using the BindableApplicationBar binding Commands and CommandParameters to the toolbar is a simple process.

In the code of my ViewModel I created a public boolean property that is set to false when the button should be disabled in the view.

        private bool buttonEnabled;
        public bool ButtonEnaled
        {
            get { return buttonEnabled; }
            set 
            {
                buttonEnabled = value;
                RaisePropertyChanged(() => ButtonEnaled);
            }
        }

On the view side I then bind the button on the BindableApplicationBar to the ButtonIsEnabled property from the ViewModel.

     xmlns:bar="clr-namespace:BindableApplicationBar;assembly=BindableApplicationBar" 
    <bar:Bindable.ApplicationBar>
        <bar:BindableApplicationBar>
            <bar:BindableApplicationBarButton 
                Text="Calculate" 
                IconUri="/Assets/AppBar/check.png"
                Command="{Binding ButtonActionCommand}" 
		IsEnabled="{Binding ButtonEnaled, Mode=TwoWay}"/>
        </bar:BindableApplicationBar>
    </bar:Bindable.ApplicationBar>

In theory this should work. But sadly, it does not. Because the Button’s Command property is set, the Command’s CanExecute method overrides the IsEnabled flag. So setting the CanExecute value to false(Show simplistically here) should disable the button

        ButtonActionCommand.CanExecute(false);

and we can set the XAML for the button like this

    <bar:Bindable.ApplicationBar>
        <bar:BindableApplicationBar>
            <bar:BindableApplicationBarButton 
                Text="Calculate" 
                IconUri="/Assets/AppBar/check.png"
                Command="{Binding ButtonActionCommand}" 
        </bar:BindableApplicationBar>
    </bar:Bindable.ApplicationBar>

Doing this does not work either. To set the IsEnabled state of the button you have to set both the CanExecute Method and the IsEnabled property values. This might be a bug in the control. But for now it is a workaround.

        private bool buttonEnabled;
        public bool ButtonEnaled
        {
            get { return buttonEnabled; }
            set 
            {
                buttonEnabled = value;
		ButtonActionCommand.CanExecute(value);
                RaisePropertyChanged(() => ButtonEnaled);
            }
        }
    <bar:Bindable.ApplicationBar>
        <bar:BindableApplicationBar>
            <bar:BindableApplicationBarButton 
                Text="Calculate" 
                IconUri="/Assets/AppBar/check.png"
                Command="{Binding ButtonActionCommand}" 
		IsEnabled="{Binding ButtonEnaled, Mode=TwoWay}"/>
        </bar:BindableApplicationBar>
    </bar:Bindable.ApplicationBar>

After some trial and error I finally managed to enable and disable buttons on the application bar as and when I need to. Happy days.

Advertisements

4 thoughts on “Disabling a button on Windows Phone Application Bar

  1. Kim

    Thank you so much! Helped me a lot. Especially the Mode=TwoWay I was missing (for whatever reason that must be set).

  2. Hi, I’ve spent almost a day to come to the pretty same solution. Anyway, thanks for sharing. You confirmed my suspicions. Who the heck developed that appbarbutton? Schoolchildren?…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s