Migrating to ArcGIS for Windows Mobile 3.0

This post has some tips for people wanting to migrate custom tasks and extensions written for the ArcGIS Runtime SDK for Windows Mobile. Before reading you should also check the article on the Esri resource center for migrating your applications to ArcGIS Mobile 3.0 as it contains some additional information that may be of help.

With the release of the 3.0 SDK there have been a number of changes to the way that custom extensions work and are deployed. Lets start with changes to the code for creating a custom task and project extension.

For the project center definition, previously you would have declared your task as

CustomTask : UserControl, IProjectTask

in 3.0 this becomes

CustomTask : ProjectTaskControl

The ProjectTaskControl type is simpler to work with. You can still set properties on it and an Icon but instead of using XML serialisation it now uses JSON. A sample base class for a task may be

public abstract class TaskBase : ProjectTaskControl
{
    readonly string _taskName;

    protected TaskBase(string taskName)
    {
        _taskName = taskName;
    }

    /// <summary>
    /// Gets/sets Description for your capability
    /// </summary>
    public override string Description
    {
        get { return base.Description; }
        set
        {
            base.Description = value;
            RaisepropertyChangedEvent("Description");
            IsDirty = true;
        }
    }

    /// <summary>
    /// Gets/sets DisplayName for your capability
    /// </summary>
    public override string DisplayName
    {
        get { return base.DisplayName; }
        set
        {
            base.DisplayName = value;
            RaisepropertyChangedEvent("DisplayName");
            IsDirty = true;
        }
    }

    public override ImageSource Icon
    {
        get
        {
            var uri = new Uri(string.Format("pack://application:,,,/SampleTasks;Component/Assets/{0}.png", _taskName));
            return new BitmapImage(uri);
        }
    }

    /// <summary>
    /// Generates an object from its JSON representation.
    /// </summary>
    public override void ReadJson(IDictionary<string, object> readData)
    {
        if (!readData.ContainsKey("Attributes"))
            return;
        IDictionary<string, object> values = readData["Attributes"] as Dictionary<string, object>;
        DisplayName = values["name"] as string;
        Description = values["description"] as string;
    }

    /// <summary>
    /// Converts an object into its JSON representation.
    /// </summary>
    public override void WriteJson(IDictionary<string, object> writeData)
    {
        IDictionary<string, object> values = new Dictionary<string, object>();
        writeData.Add("Attributes", values);
        values.Add("name", DisplayName);
        values.Add("description", Description);
    }
}

and used as

public sealed partial class CustomTask : TaskBase
{
    public SearchTask() : base("CustomTask")
    {
        InitializeComponent();

        DisplayName = "My custom task";
        Description = "blah blah blah.";
    }
}

For the implementation of the Task in the windows or windows mobile dll respectively the type is not changed though you must include the JSON serialisation. Without this you won’t see your task in the deployed application.

/// <summary>
/// Generates an object from its JSON representation
/// </summary>
public override void ReadJson(IDictionary<string, object> readData)
{
    if (!readData.ContainsKey("Attributes"))
        return;
    IDictionary<string, object> values = readData["Attributes"] as Dictionary<string, object>;
    Name = values["name"] as string;
    Description = values["description"] as string;
}

/// <summary>
/// Converts an object into its JSON representation.
/// </summary>
public override void WriteJson(IDictionary<string, object> writeData)
{
    IDictionary<string, object> values = new Dictionary<string, object>();
    writeData.Add("Attributes", values);
    values.Add("name", Name);
    values.Add("description", Description);
}

Writing a project extension has seen a similar change required so now instead of

public partial class CustomExtension : UserControl, IProjectExtension

you would use

public sealed partial class CustomExtension : ProjectExtensionControl

The other important change is to how extensions are deployed. Now when you build your projects you set the path to be

c:\ProgramData\ESRI\MobileProjectCenter\Extensions for the project center dll

c:\ProgramData\ESRI\MobileProjectCenter\Extensions\Win32 for the windows application dll and

c:\ProgramData\ESRI\MobileProjectCenter\Extensions\WinCE for the windows mobile dll

These dlls are automatically packaged with a mobile project when you reference them in the mobile project center and will be copied to a subfolder of the project. This means that if you want to debug your code you need either change the output path of your library to match your project location or manually copy the built dll each time you make code changes so that you are using the latest version. You could also add a build event to do this. If you forget this step then you will see a message like

debugarcgismobileerror

Now you can add and deploy your code there may be some breaking changes in the API that you need to correct, here are some that I have encountered.

When using a sketch tool you now need to call Activate on it

var sketchTool = new EnvelopeSketchTool();
sketchTool.SketchCompleted += SketchToolOnSketchCompleted;
sketchTool.AttachToSketchGraphicLayer(_graphicsLayer);
sketchTool.Activate();

Setting layer visibility has moved to the MobileCacheMapLayerDefinition

internal static void ToggleLayerVisibility(string layerName)
{
    if (string.IsNullOrEmpty(layerName)) return;

    var layer = MobileApplication.Current.Project.EnumerateFeatureSourceInfos().FirstOrDefault(lyr => string.Equals(lyr.Name, layerName, StringComparison.InvariantCultureIgnoreCase));

    if (layer == null) return;

    layer.MobileCacheMapLayerDefinition.Visibility = !layer.MobileCacheMapLayerDefinition.Visibility;
}

When checking for a layer you now use FeatureSourceInfo

MobileApplication.Current.Project.EnumerateFeatureSourceInfos()

Hopefully you find these tips useful for helping update your own code. Let me know of any other useful information that I’ve missed.

Advertisements

4 comments

  1. Dave,

    I am working on a Mobile Project Center extension and I need the ability to reference the operational layers in the map. Similar to how the built in Search Tasks lets you select a Feature Layer to build its custom queries. There is no reference like MobileApplication, or ArcGIS that provides access to the Feature layers. Would you happen to know how to retrieve this information?

    Thanks,
    -Joe Cox

      1. I may be missing something. That is how I am accessing the layers within the extension that runs in ArcGIS for Windows Mobile on my device, but when I try accessing the file this way within the mobile project center extension it throws an error. I have attached a screen shot, just to make sure we are on the same page. I really appreciate any help. The documentation on customizing a mobile project center extension seems to be non-existent.

        http://imgur.com/LrZwThY

      2. Hi,

        ah OK. When you are in the project center itself you don’t have access to the MobileApplication as it is not running so it’s a different context. I’m not sure off the top of my head how you would achieve what you want though I’d suggest running in DEBUG mode to see what you can access and using a decompiler like dotPeek or JustDecompile to see how the Project Center code works for building a list of layers. I haven’t got the SDK installed at the moment so I can’t look into it but hopefully that gives you a starting point.

        Cheers,
        Dave

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s