Wednesday, October 6, 2010

Windows Phone 7 Quick Tip #17 – Enable/Disable Menu Bar

Here’s another quick one I ran into while testing my application.  I need to submit data to a web service and wait for a response.  While they phone is talking to the web service, I don’t want the user to send the same request twice.  Initiating the send takes place on the app bar.

image

We need to disable the app bar button.  If you attempt to use the control name you assign to the button it will throw a null reference exception.  Not a very good UX.  My initial solution that I put in place and held my nose was similar to:

((ApplicationBarIconButton)ApplicationBar.Buttons[0]).Enabled = false;

Don’t get me started on what I don’t like about that approach, ok?

I came across an instance where I needed to disable two buttons, I just couldn’t handle the smell of:

((ApplicationBarIconButton)ApplicationBar.Buttons[0]).Enabled = false;((ApplicationBarIconButton)ApplicationBar.Buttons[1]).Enabled = false;

And decided to do something about it.  My solution is a simple extension method that looks like:

namespace Microsoft.Phone.Shell
{
    public static class ApplicationBarHelpers
    {
        public static void Enable(this IApplicationBar appBar)
        {
            appBar.IsMenuEnabled = true;

            foreach (var obj in appBar.Buttons)
            {
                var button = obj as ApplicationBarIconButton;
                if (button != null)
                    button.IsEnabled = true;
            }
        }

        public static void Disable(this IApplicationBar appBar)
        {
            appBar.IsMenuEnabled = false;

            foreach (var obj in appBar.Buttons)
            {
                var button = obj as ApplicationBarIconButton;
                if (button != null)
                    button.IsEnabled = false;
            }
        }
    }
}

Something still smells above…should be able to get rid of some lines of code but don’t want to get too side tracked.  Kudo’s and a mention to anyone that can do a little cleanup.

Just include the using Microsoft.Phone.Shell to pickup the namespace within your .cs file and you can do the following:

 

ApplicationBar.Enable();

and

ApplicationBar.Disable();

Which I think is much cleaner.

-twb

4 comments:

  1. Hi Kevin,
    I’ve been reading your blog of awhile now and was wondering if you would if I shared some of your WP7 tips with my LinkedIn Group “Windows Phone Community @ Microsoft”. You’re content is excellent.
    If you ever make it out to Redmond for a conference, would like to make your acquaintance.
    Thanks in advance for your time,
    -James Temple
    a-jatem@microsoft.com

    ReplyDelete
  2. Thanks, this is great - but I really wanted to be able to enable/disable the actual buttons so I did the following - it's still a bit of a hack but couldn't see any other way to do it:

    In the extension class add this:

    public static void EnableButton(this IApplicationBar appBar, int buttonID)
    {
    ApplicationBarIconButton btn = (ApplicationBarIconButton)appBar.Buttons[buttonID];
    btn.IsEnabled = true;
    }

    public static void DisableButton(this IApplicationBar appBar, int buttonID)
    {
    ApplicationBarIconButton btn = (ApplicationBarIconButton)appBar.Buttons[buttonID];
    btn.IsEnabled = false;
    }

    I have four buttons in my appbar (Back, Refresh, Add, EDit) so I added an enumeration to my mainpage.cs like so:

    private enum AppBarButtons
    {
    Back,
    Refresh,
    Add,
    Edit
    }

    Then I can enable/disable each button in my code like so:

    ApplicationBarHelpers.EnableButton(this.ApplicationBar, (int)AppBarButtons.Back);
    ApplicationBarHelpers.DisableButton(this.ApplicationBar, (int)AppBarButtons.Refresh);

    As I say, I know it's a hack but at least if you change the buttons (or their order) you only need to change the enumeration - as long as the order of the buttons on the appbar is the same as the order they appear in the enumeration obviously.

    Hope this helps someone... you article helped me get this sorted so many thanks for that.

    ReplyDelete
  3. am planing for digital clock program...
    if the user uses the buttons he can change the time...
    but if he want to edit n change them by clicking on the textbox...
    i want the the number buttons to pop up(i.e visible) else should be hidden....
    can u suggest me a code for hiding the buttons n showing them upon an action even....

    ReplyDelete
  4. Appbar works great but when I use

    this.Content = new PAGE(Constructor1, Constructor1, Constructor1);

    to navigate to other page....App bar doesn't show up....:|

    Any Idea???

    ReplyDelete