Gode rutiner: kartinteraksjon

Når du skriver et verktøy for ArcGIS Map-webdelen som krever bruk av musen, bruker du Draw-overflaten i stedet for å lytte etter museklikk. Med Draw-overflaten kan du enkelt få tak i geometrier som brukere av programmet har opptegnet. Når du har hentet disse geometriene, kan du legge dem til i et grafikklag eller bruke dem som inndata for andre operasjoner.

Når du skriver et verktøy som fanger opp klikk på kartet, gjør du følgende:

  • Bruk Draw-objektet for å fange opp inndata fra musen. Husk at det også kan være andre verktøy i det gjeldende Viewer-programmet som fanger opp klikk på kartet. Du bør derfor alltid bruke Draw-objektet i stedet for å lytte etter kartets MouseClick-hendelse direkte, ettersom bare ett Draw-objekt kan være aktivt om gangen. Hvis et Draw-objekt aktiveres mens et annet Draw-objekt allerede er aktivt, blir Draw-objektet som ble forsøkt aktivert, automatisk deaktivert.
  • Lytt etter endringer i Draw-objektets IsEnabled-egenskap for å håndtere tilfeller der verktøyets Draw-objekt har blitt deaktivert automatisk. Hvis du for eksempel implementerer et identifiseringsverktøy der du har et aktivt Draw-objekt, til å fange opp klikk på kartet og en dialogboks til å vise identifiseringsresultater, vil du trolig at dialogboksen skal lukkes når et annet verktøy som fanger opp kartinndata, blir valgt. Du må da lytte etter endringer i IsEnabled-egenskapen.

Den følgende kodesnutten oppretter en ny Draw-overflate på kartet, setter DrawMode til Point og lytter etter IsEnabled-egenskapen.

private Identify identifyDialog;
private IdentifyTask identifyTask;
private Draw draw;

public void Execute(object parameter)
{
    if (draw == null)
    {
         draw = new Draw(MapApplication.Current.Map) { DrawMode = ESRI.ArcGIS.Client.DrawMode.Point };
         draw.DrawComplete += DrawComplete;

         // Listen to the IsEnabled property.  This is to detect cases where other tools have
         // disabled the Draw surface.
				     // Utils class shown below.
         Utils.RegisterForNotification("IsEnabled", draw, identifyDialog, OnDrawEnabledChanged);
     }

     draw.IsEnabled = true;
     MapApplication.Current.ShowWindow("Identify", identifyDialog, false, null, IdentifyDialogHidden);
}

// Fires when the drawing action is complete.  Issues an identify operation using the drawn geometry.
private void DrawComplete(object sender, DrawEventArgs e)
{
    MapPoint clickPoint = e.Geometry as MapPoint;

    IdentifyParameters identifyParams = new IdentifyParameters()
    {
        Geometry = clickPoint,
        MapExtent = MapApplication.Current.Map.Extent,
        LayerOption = LayerOption.visible,
        SpatialReference = MapApplication.Current.Map.SpatialReference
    };

    if (identifyTask.IsBusy)
        identifyTask.CancelAsync();
    identifyTask.ExecuteAsync(identifyParams);

    GraphicsLayer graphicsLayer = MapApplication.Current.Map.Layers["IdentifyResultsLayer"] as GraphicsLayer;
    if (graphicsLayer == null)
    {
        graphicsLayer = createResultsLayer();
        MapApplication.Current.Map.Layers.Add(graphicsLayer);
    }
    else
    {
        graphicsLayer.ClearGraphics();
    }

    Graphic graphic = new Graphic() { Geometry = clickPoint };
    graphicsLayer.Graphics.Add(graphic);
}
public class Utils
{
   public static void RegisterForNotification(string propertyName, object source, FrameworkElement element, 
   PropertyChangedCallback callback)
   {
       //Bind to a depedency property.
       Binding b = new Binding(propertyName) { Source = source };
       var prop = System.Windows.DependencyProperty.RegisterAttached(
            "ListenAttached" + propertyName,
            typeof(object),
            typeof(UserControl),
            new PropertyMetadata(callback));

       element.SetBinding(prop, b);
   }
}