How to Load DotSpatial Extensions Into My Toolbar

Introduction

DotSpatial is an open-source project that contains controls which can be used to manipulate and display geographic information. As DotSpatial is extensible, developers may find they want to load extensions create by others. This article describes the requirements for loading extensions that interact with the user interface.

Downloading DotSpatial and Creating a Project

This article is based on the DotSpatial 1.0 Release located on the downloads tab at http://dotspatial.codeplex.com

If you are not familiar with creating a simple DotSpatial-based application, please consider the introductory article and basic extension loading. For practical purposes, we assume you are coming to this article after having completed the previous ones.

Extension Interfaces

In order to provide extension developers (those writing a class that inherits from Extension or IExtension) with a simpler experience, we guarantee that they will have access to a Docking Manager, Header Control, and Status Control. This means they can create docking panels, ribbon buttons or menu items, and progress messages.

We don’t want these developers to worry about checking first to see if a header control or progress bar is available, so we categorically require that the application developer implement IDockManager, IHeaderControl, and IStatusControl. If you’re feeling like implementing these is going to be too much work, you might also ask “should I create an extension or an application?” You don’t need to implement these interfaces to support ITool or IDataProvider based extensions.

We’ve provided a few implementations which are available in the feed, such as DotSpatial.Plugins.Ribbon, which implements IHeaderControl and IStatusControl and DotSpatial.Plugins.DockManager, which implements IDockManager.

These can be consumed as nuget packages, or you can download them as zip files. Locate the zip url as the tag that begins with

content type="application/zip"

The aforementioned assemblies presently have the requirement that your main form export a Shell (see DemoMap), so that they understand to what form they should attach themselves.

Implementing IHeaderControl

Let’s examine the DemoMap project for a sample implementation of IHeaderControl.

[Export(typeof(IHeaderControl))]
public class SimpleHeaderControl : MenuBarHeaderControl, IPartImportsSatisfiedNotification
{
    private ToolStripContainer toolStripContainer1;

    [Import("Shell", typeof(ContainerControl))]
    private ContainerControl Shell { get; set; }

    ///

    /// Called when a part's imports have been satisfied and it is safe to use. (Shell will have a value)
    ///

public void OnImportsSatisfied() { this.toolStripContainer1 = new ToolStripContainer(); this.toolStripContainer1.ContentPanel.SuspendLayout(); this.toolStripContainer1.SuspendLayout(); this.toolStripContainer1.Dock = DockStyle.Fill; this.toolStripContainer1.Name = “toolStripContainer1”; // place all of the controls that were on the form originally inside of our content panel. while (Shell.Controls.Count > 0) { foreach (Control control in Shell.Controls) { this.toolStripContainer1.ContentPanel.Controls.Add(control); } } Shell.Controls.Add(this.toolStripContainer1); this.toolStripContainer1.ContentPanel.ResumeLayout(false); this.toolStripContainer1.ResumeLayout(false); this.toolStripContainer1.PerformLayout(); Initialize(toolStripContainer1); } }

Note the attribute decorating the SimpleHeaderControl class.

[Export(typeof(IHeaderControl))]

This attribute declares that this is the header control that we are exporting. We can only export one header control, one status control, and  one dock manager; otherwise when extensions are loaded, it is not clear which one should be used.

SimpleHeaderControl provides a menu and toolbar implementation and is derived from DotSpatial.Controls.Header.MenuBarHeaderControl which does the bulk of the work and requires only a ToolStripContainer where it can place menu items and toolbar buttons.

In the listed code you can see we nest any controls that were on the shell form inside of the content panel so that the menu and toolbar are docked outside (above) them.

If you are not able to derive from MenuBarHeaderControl, you will need to provide similar functionality but should be able to derive from HeaderControl, which keeps track of which items are added by what extension and implements the RemoveAll() method.

Points of Interest

You can test your implementation, by loading the DotSpatial.Plugins.MenuBar assembly.

The DemoMap.exe contains code that meets the requirements for loading extensions. Instead of creating a separate sample in this article, please reference that code.

DotSpatial 1.7 requires and extra line of code to display the default buttons in the header control. InstantiateSnippet

new DotSpatial.Controls.DefaultMenuBars(appManager1).Initialize(appManager1.HeaderControl);

2 thoughts on “How to Load DotSpatial Extensions Into My Toolbar

  1. Pingback: Composing an Application by using Extensions « Mudnug

Leave a comment