Customizing the application and GPS menus

The application window contains a global menu that is available at all times, regardless of which page is currently displayed. The content of this menu is bound to the MenuItems collection on the MobileApplication class. To customize the application menu, you simply need to add or remove items from this collection.

To modify this collection, you first need to obtain a reference on the MobileApplication object. MobileApplication is a singleton class, and a reference to the one and only instance may be obtained with the static MobileApplication.Current property.

public staticMobileApplication Current { get; }

The MenuItems property is defined as ObservableCollection<object>. It holds menu items listed in the application menu; similarly, you can access GPS menu items from GpsMenuItems.

Because, in WPF, the content of a menu (and virtually any other WPF control) is not limited to one specific type (for example, m), MobileApplication.MenuItems is a collection of type object. An item in this collection may be something simple like MenuItem, or it may be complex like Border containing DockPanel with an Image control and TextBlock. In most cases, though, MenuItem is sufficient.

public  ObservableCollection<object> MenuItems { get; }

Adding an item to the collection is as simple as instantiating a new menu item, setting its properties, and adding/inserting it into the collection. The following creates a new menu item and adds it as the first item in the collection:

MenuItem  menuItem = new  MenuItem();
menuItem.Header = "Hello";
MobileApplication.Current.MenuItems.Insert(0, menuItem);

Unfortunately, this new menu item isn't very useful because it won't do anything when it's clicked. To make the menu item actually do something, use a WPF command to perform some action when the menu item is clicked. In WPF, there is an ICommand interface containing two methods: CanExecute and Execute. Many controls in WPF-like Button and MenuItem have built-in support for commands. These controls allow an ICommand interface to be associated with them, which will invoke the command's Execute method when some action occurs on the control (for example, when the control is clicked). The ICommand.CanExecute method returns a Boolean value indicating whether the command's Execute method can be invoked. This is useful when associated with a control because it allows the control to disable itself.

To make implementing an ICommand class easier, the application framework provides a helper class called RelayCommand. RelayCommand implements ICommand using delegates for Execute and CanExecute. To use RelayCommand, you simply instantiate a new instance, passing it an Execute delegate and an optional CanExecute delegate. These delegates will be invoked when the command's Execute and CanExecute methods are called.

public class  RelayCommand : ICommand
{
  public RelayCommand(Action<object> execute);
  public RelayCommand(Action<object> execute, Predicate<object> canExecute);
}

Now you can add some behavior to the menu item with RelayCommand.

class MyExtension : ProjectExtension
{
  private MenuItem _menuItem;
  protected override void OnOwnerInitialized()
  {
    _menuItem= new MenuItem();
    _menuItem.Heamder = "Hello";
    _menuItem.Comand = new RelayCommand(param => this.MyCommandExecute(), param => this. MyCommandCanExecute());
    MobileApplication.Current.MenuItems.Insert(0, _menuItem);
  }

  private bool ApplicationCommandCanExecute()
  {
    return true; // returning false will disable the menu item
  }
 
  private void MyCommandExecute()
  {
    System.Windows.MessageBox.Show("You clicked my menu item!");
  }
 
  protected override void Uninitialize()
  {
    // Remove the item we added in OnOwnerInitialized 
    MobileApplication.Current.MenuItems.Remove(_menuItem);
    _applicationMenuItem = null;
  }
}

9/20/2011