Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Windows Phone - ApplicationBar Controller

0.00/5 (No votes)
3 Oct 2012 1  
A Windows Phone ApplicationBar controller.

This article is also published in my blog.

Introduction 

While doing some awesome side project in Windows Phone, I needed a way to have a better control on the Application Bar. I want the ApplicationBar Icon Buttons and Menu Items to be dynamically added, removed, hide/show, or enable/disable, as well as hooking an event for the specific Icon Button or Menu Items.  

Background 

What is an ApplicationBar in Windows Phone and how to use it? 

In Windows Desktop development, we have a control called Toolbar where you can add a Button, Drop Down Menu, Label, Textbox, or Progressbar and also you can add an Icon to your Buttons or Labels as well. 

You can have a button as many as you want, position the control around the Form, and you can also have a toolbar on all sides of your Form. 

In Windows Phone, it also has some sort of Toolbar, but it is called "Application Bar". 

The Application Bar can have a set of circled white icons that stays at the bottom of the screen if it's in Portrait mode, or at the Right, if you turned your phone in Landscape. The Application Bar can only have two controls and that is, the Icon Button and a Menu Item. Just like what you see below (courtesy from Microsoft) 

Unfortunately, it is limited, because you're pretty much stuck of having a maximum of 4 Icon Buttons but lucky enough on the other hand for the Menu Item because you can add as much as you can. 

But our main concern is the usability of the Icon Buttons because if you think of a big project, you pretty much has to have different ways of letting your end-users easily navigate around your application and one of them is using an ApplicationBar, but having a maximum of 4 Icon Buttons, is not enough.  

So how do we solve the problem? 2 ways, either create a multiple Application Bars or have your Icon Buttons dynamically changing at run-time. Which one do you choose? 

Let's take a moment of showing an example of creating a multiple Application Bars. In Windows Phone DevCenter, they wrote a way to do this 

How to: Create an Application Bar in Code for Windows Phone 

http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394036(v=vs.92).aspx 

As you can see from their example, they have two Application Bars defined in XAML. 

Now the problem is, it may soon get very long and unmanageable by means of having a duplicate Menu Items (like what you see there), and what if I have 4 different Application Bars and I need a specific Icon Button to always appear on those Application Bars? So what I have to do is to Copy & Paste the XAML definition of that Icon Button to each Application Bar. Possibly, in overtime, I have to change the icon and text, so I have to go over to each Application Bars and change it again. Manipulating the Icon Buttons on those Application Bars in run-time will again introduce another headache. 

So what if we could create an easy way of controlling our Icon Buttons in just one single Application Bar? 

I wrote a class called ApplicationBarController to address the problem where we can have a much smoother control over to our Icon Buttons and Menu Items in one Application Bar. What we can do in this class is we can easily Show the Icon Buttons or Menu Items we need for a specific task, as well as Hide them if not needed anymore like. In the animated image above, I demoed how this class works. 

Using the code  

ApplicationBarController  class 

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Microsoft.Phone.Shell;

namespace CAPPLOUD.WP.Controllers
{
    public class ApplicationBarController
    {
        IApplicationBar _appbar;

        public ApplicationBarController(IApplicationBar appbar)
        {
            this._appbar = appbar;
        }

        Dictionary<string, IApplicationBarIconButton> Buttons { get; set; }
        Dictionary<string, IApplicationBarMenuItem> MenuItems { get; set; }

        /// <summary>
        /// Add new Menu Item to the collection.
        /// Must call ShowMenuItems or ShowMenuItem to show the menu
        /// </summary>
        /// <param name="Text">Name of the menu item</param>
        /// <param name="isEnabled"></param>
        /// <param name="e">Delegated event</param>
        public void AddNewMenuItem(string Text, bool isEnabled, EventHandler e)
        {
            if (MenuItems == null)
            {
                MenuItems = new Dictionary<string, IApplicationBarMenuItem>();
            }

            if (MenuItems.ContainsKey(Text)) { return; }

            ApplicationBarMenuItem menuitem = new ApplicationBarMenuItem()
            {
                Text = Text,
                IsEnabled = isEnabled
            };
            menuitem.Click += e;

            MenuItems.Add(Text, menuitem);
        }
        /// <summary>
        /// Add new Icon Button to the collection.
        /// Must call ShowButtons or Showbutton to show the icon button
        /// </summary>
        /// <param name="Text">Text of the icon button</param>
        /// <param name="IconUri">Relative image url</param>
        /// <param name="isEnabled"></param>
        /// <param name="e">Delegated event</param>
        public void AddNewButton(string Text, string IconUri, bool isEnabled, EventHandler e)
        {
            if (Buttons == null)
            {
                Buttons = new Dictionary<string, IApplicationBarIconButton>();
            }

            if (Buttons.ContainsKey(Text)) { return; }

            ApplicationBarIconButton btn = new ApplicationBarIconButton()
            {
                Text = Text,
                IconUri = new Uri(IconUri, UriKind.Relative),
                IsEnabled = isEnabled
            };
            btn.Click += e;
            
            Buttons.Add(Text, btn);
        }

        /// <summary>
        /// Replace and show selected buttons in the application bar
        /// </summary>
        /// <param name="ButtonText">Icon Button texts to show</param>
        public void ShowButtons(params string[] ButtonText)
        {
            this._appbar.Buttons.Clear();

            foreach (string text in ButtonText)
            {
                if (!_appbar.Buttons.Contains(Buttons[text]))
                {
                    _appbar.Buttons.Add(Buttons[text]);
                }
            }
        }
        /// <summary>
        /// Append the icon button in the application bar
        /// </summary>
        /// <param name="ButtonText">Icon Button texts to show</param>
        public void ShowButton(params string[] ButtonText)
        {
            foreach (string text in ButtonText)
            {
                if (!_appbar.Buttons.Contains(Buttons[text]))
                {
                    _appbar.Buttons.Add(Buttons[text]);
                }
            }
        }
        /// <summary>
        /// Remove selected buttonsin the application bar
        /// </summary>
        /// <param name="ButtonText">Icon Button texts to show</param>
        public void RemoveButtons(params string[] ButtonText)
        {
            foreach (string text in ButtonText)
            {
                if (_appbar.Buttons.Contains(Buttons[text]))
                {
                    _appbar.Buttons.Remove(Buttons[text]);
                }
            }
        }
        /// <summary>
        /// Clear all Icon Buttons in the application bar
        /// </summary>
        public void RemoveButtons()
        {
            this._appbar.Buttons.Clear();
        }
        /// <summary>
        /// Enable or Disable selected buttons
        /// </summary>
        /// <param name="Enabled"></param>
        /// <param name="ButtonText">Icon Button texts to Enable or Disable</param>
        public void EnableButtons(bool Enabled, params string[] ButtonText)
        {
            foreach (string text in ButtonText)
            {
                Buttons[text].IsEnabled = Enabled;
            }
        }

        /// <summary>
        /// Replace and show selected menu items in the application bar
        /// </summary>
        /// <param name="MenuItemText">menu items texts to show</param>
        public void ShowMenuItems(params string[] MenuItemText)
        {
            this._appbar.MenuItems.Clear();

            foreach (string text in MenuItemText)
            {
                if (!_appbar.MenuItems.Contains(MenuItems[text]))
                {
                    _appbar.MenuItems.Add(MenuItems[text]);
                }
            }
        }
        /// <summary>
        /// Append the menu items in the application bar
        /// </summary>
        /// <param name="MenuItemText">menu items texts to show</param>
        public void ShowMenuItem(params string[] MenuItemText)
        {
            foreach (string text in MenuItemText)
            {
                if (!_appbar.MenuItems.Contains(MenuItems[text]))
                {
                    _appbar.MenuItems.Add(MenuItems[text]);
                }
            }
        }
        /// <summary>
        /// Remove selected menu items in the application bar
        /// </summary>
        /// <param name="MenuItemText">menu items texts to show</param>
        public void RemoveMenuItems(params string[] MenuItemText)
        {
            foreach (string text in MenuItemText)
            {
                if (_appbar.MenuItems.Contains(MenuItems[text]))
                {
                    _appbar.MenuItems.Remove(MenuItems[text]);
                }
            }
        }
        /// <summary>
        /// Clear all menu items in the application bar
        /// </summary>
        public void RemoveMenuItems()
        {
            _appbar.MenuItems.Clear();
        }
        /// <summary>
        /// Enable or Disable selected menu items
        /// </summary>
        /// <param name="Enabled"></param>
        /// <param name="MenuItemText">menu items texts to Enable or Disable</param>
        public void EnableMenuItems(bool Enabled, params string[] MenuItemText)
        {
            foreach (string text in MenuItemText)
            {
                MenuItems[text].IsEnabled = Enabled;
            }
        }

        /// <summary>
        /// Show or Hide application bar
        /// </summary>
        /// <param name="Show"></param>
        public void ShowAppBar(bool Show)
        {
            if (this._appbar.IsVisible != Show)
            {
                this._appbar.IsVisible = Show;
            }
        }
    }
}

This ApplicationBarController class can pretty much do what ever you want. You can: 

  • Add or Remove an Icon Button or Menu Items 
  • Show or Hide Icon Buttons or Menu Items 
  • Enable or Disable an Icon Button or Menu Items. 

Here's an easy way you can implement ApplicationBarController class. 

First thing you have to do is to hook the ApplicationBar for the current page. 

// Hook the ApplicationBar in the current page
ApplicationBarController appbar = new ApplicationBarController(this.ApplicationBar); 

Next is to prepare your Icon Buttons and Menu Items that you are going to need in your project. 

void InitializeApplicationBar
{
    // prepare all Icon Buttons and Menu Items
    this.appbar.AddNewButton("add", "/icons/appbar.add.rest.png", 
                             true, ApplicationBarIconButton_Click);
    this.appbar.AddNewButton("save", "/icons/appbar.save.rest.png", 
                             true, ApplicationBarIconButton_Click);
    this.appbar.AddNewButton("cancel", "/icons/appbar.close.rest.png", 
                             true, ApplicationBarIconButton_Click);
    this.appbar.AddNewButton("delete", "/icons/appbar.delete.rest.png", 
                             true, ApplicationBarIconButton_Click);
    this.appbar.AddNewButton("clear", "/icons/appbar.close.rest.png", 
                             true, ApplicationBarIconButton_Click);

    this.appbar.AddNewButton("ff", "/icons/appbar.transport.ff.rest.png", 
                             true, ApplicationBarIconButton_Click);
    this.appbar.AddNewButton("play", "/icons/appbar.transport.play.rest.png", 
                             true, ApplicationBarIconButton_Click);
    this.appbar.AddNewButton("pause", "/icons/appbar.transport.pause.rest.png", 
                             true, ApplicationBarIconButton_Click);
    this.appbar.AddNewButton("rew", "/icons/appbar.transport.rew.rest.png", 
                             true, ApplicationBarIconButton_Click);

    this.appbar.AddNewButton("add menu", "/icons/appbar.add.rest.png", 
                             true, ApplicationBarIconButton_Click);
    this.appbar.AddNewButton("clear menus", "/icons/appbar.close.rest.png", 
                             true, ApplicationBarIconButton_Click);
    this.appbar.AddNewMenuItem("Message", true, ApplicationBarMenuItem_Click);
}

private void ApplicationBarIconButton_Click(object sender, EventArgs e)
{
    ApplicationBarIconButton btn = (ApplicationBarIconButton)sender;
    string text = btn.Text.ToLower();
    
    // your conditions here
    if (text == "add")
    {
        MessageBox.Show("Add button was clicked");
    }
    // add more conditions here
}

private void ApplicationBarMenuItem_Click(object sender, EventArgs e)
{
    ApplicationBarMenuItem menu = (ApplicationBarMenuItem)sender;
    string text = menu.Text.ToLower();
    
    // your conditions here
}

Then while at run time, you can simple show the Icon Buttons or Menu Items you need for the current task in your page.

this.appbar.ShowButtons(new string[] { "add", "delete", "clear" });
// or the same as
this.appbar.ShowButtons("add", "delete", "clear");
// or
this.appbar.ShowButtons("add", "clear"); 

and the same way with Menu Items. 

One important note is, the Text you give to the Icon Button or Menu Items acts as a case sensitive Key.

Ending 

I hope from that class, I am able to help you with your Windows Phone development.

Cheers 

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here