Map page

The Windows application framework exposes the ESRI.ArcGIS.Mobile.Client.Tasks.ViewMap.ViewMapPage class for the map page used in the map viewing workflow. You can reuse this map page in your workflow: just navigate to it as you would to any other pages in the application framework.

MobileApplication.Current.Transition(new ESRI.ArcGIS.Mobile.Client.Tasks.ViewMap.ViewMapPage());

Since ViewMapPage is derived from MobileApplicationPage, it inherits the page title, note, Back/Cancel button, OK button, and page menu on the navigation pane. These items can be customized in the same way as other pages within the application. Besides these, the map control menu on the map control can be customized as well.

ViewMapTask viewMapTask = (ViewMapTask)MobileApplication.Current.Project.Tasks.GetFirstExtensionOfType(typeof(ViewMapTask));

ViewMapPage is accessible as a property of ViewMapTask:

ViewMapPage viewMapPage = viewMapTask.ViewMapPage;

MapControl is accessible via a property of ViewMapPage:

MapControl mapControl = viewMapPage.MapControl;

Map control menu

Now you can customize the map control's menu similar to the application menu.

class MyExtension : ProjectExtension
{
  private MapControl _mapControl;
  protected override void OnOwnerInitialized()
  {
    ViewMapTask viewMapTask = (ViewMapTask)MobileApplication.Current.Project.Tasks.GetFirstExtensionOfType(typeof(ViewMapTask));
    if (viewMapTask == null)
      return;

    _mapControl = viewMapTask.ViewMapPage.MapControl;

    MenuItem menuItem = new MenuItem();
    menuItem.Header = "Hello";
    menuItem.Command = new RelayCommand(param => this.MyMapCommandExecute());
    _workListMapControl.MenuItems.Add(menuItem);
  }

  private void MyMapCommandExecute()
  {
    StringBuilder builder = new StringBuilder();
    builder.AppendLine("You clicked my menu item!");
    builder.AppendLine(_mapControl.GetExtent().ToString());
    System.Windows.MessageBox.Show(builder.ToString());
  }
}

Another way to write this example is to use WPF RoutedUICommand instead of RelayCommand. One benefit of using RoutedUICommand is that the Execute delegate of the command binding is passed the control that raised the event as a parameter. This means, as in the example above, you do not need to retain a reference to MapControl as a member variable. This enables you to add menu items to multiple menus that all reference the same RoutedUICommand.

class MyExtension : ProjectExtension
{
  // Our (static) RoutedUICommand
  public static readonly RoutedUICommand MyRoutedMapCommand = new RoutedUICommand("Hello", "MyRoutedMapCommand", typeof(MyExtension));

  protected override void OnOwnerInitialized()
  {
    ViewMapTask viewMapTask = (ViewMapTask)MobileApplication.Current.Project.Tasks.GetFirstExtensionOfType(typeof(ViewMapTask));
    if (task == null)
      return;

    MapControl mapControl = viewMapTask.ViewMapPage.MapControl;

    // Add a new item to the map control menu in the ViewMapPage
    MenuItem menuItem = new MenuItem();
    menuItem.Header = "Hello";
    menuItem.Command = MyRoutedMapCommand;
    menuItem.CommandTarget = mapControl;
    mapControl.MenuItems.Add(menuItem);

    // Now add a command binding for our RoutedUICommand to the map control
    CommandBinding commandBinding = new CommandBinding(MyRoutedMapCommand);
    commandBinding.Executed += new ExecutedRoutedEventHandler(RoutedWorkListPageCommandBinding_Executed);
    mapControl.CommandBindings.Add(commandBinding);
  }

  void RoutedWorkListPageCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
  {
    MapControl mapControl = sender as MapControl;

    StringBuilder builder = new StringBuilder();
    builder.AppendLine("You clicked my menu item!");
    builder.AppendLine(mapControl.GetExtent().ToString());
    System.Windows.MessageBox.Show(builder.ToString());
  }
}

The above example could easily be extended to create and add another menu item associated with the same RoutedUICommand, adding it to a different map control menu on a different page but using the same Executed handler (RoutedWorkListPageCommandBinding_Executed).

Map control mouse event and graphic layer

Besides customizing the map control menu, you can access mouse events on the map control and write your own event handlers (for example, get the x,y location where you tap on the map).

...
mapControl = viewMapTask.ViewMapPage.MapControl;
mapControl.MouseMove += new System.Windows.Input.MouseEventHandler(mapControl_MouseMove);

void mapControl_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
 // get mouse location from MouseEventArgs, do something
}

To add UI controls, graphics, or text on the map control, you can add a graphic layer to the map. GraphicLayer is derived from WPF Canvas, and you can add all kinds of WPF controls on it.

GraphicLayer gl = new GraphicLayer();
MobileApplication.Current.Map.MapGraphicLayers.Add(gl); // add graphic layer to the map control
gl.GeometryBag.Add(myGeometry); // add a geometry to the graphic layer

If you want to sketch geometry on the map, attach AddVertexSketchTool to the graphic layer (via AttachToSketchGraphicLayer()), add the geometry you want to create/edit to the GraphicLayer GeometryBag collection, then make the geometry you want to create/edit the GraphicLayer SelectedGeometry.

GraphicLayer sketchLayer = new GraphicLayer();
myMap.MapGraphicLayers.Add(sketchLayer);

sketchLayer.GeometryBag.Add(myGeometry);
sketchLayer.SelectedGeometry = myGeometry;

AddVertexSketchTool sketchTool = new AddVertexSketchTool();

// The following actually starts sketching
sketchTool.AttachToSketchGraphicLayer(sketchLayer);

// When done sketching
sketchTool.DetachFromSketchGraphicLayer();

// When totally done with the sketch layer
sketchLayer.SelectedGeometry = null;
sketchLayer.GeometryBag.Remove(myGeometry);
myMap.MapGraphicLayers.Remove(sketchLayer);

It is worth mentioning that there is no concept of map actions in the WPF map control. The WPF graphic layer is what gives you the functionality to listen to and handle mouse events, which is what the sketch tools are doing. The WPF graphic layer is also what is rendering the geometry (in GeometryBag). You can also add other WPF graphics to the graphic layer to render things like rubber-band feedback (again, that is what the sketch tools are doing).

Refer to the ShowXYLocation extension and Geocoding task samples for more details.


9/20/2011