Professional Documents
Culture Documents
Building A Map Viewing Application Using The ArcGIS Engine Controls
Building A Map Viewing Application Using The ArcGIS Engine Controls
Engine Runtime
ArcView
ArcEditor
ArcInfo
Additional Requirements
In this topic
Project description
Concepts
Design
Implementation
Deployment
Additional resources
Project description
This document demonstrates the steps required to create a GIS application for viewing pre-authored
ESRI map documents (*.mxd).
Concepts
This scenario is implemented using the Microsoft Visual Studio .NET development environment and
uses the ESRI interop assemblies to host the ArcGIS Engine controls inside .NET Windows controls in a
.NET form. These interoperability assemblies act as a bridge between the unmanaged code of the
Component Object Model (COM) and the managed .NET code. Any references to the members of the
COM ArcGIS Engine controls are routed to the interop assemblies and forwarded to the actual COM
object. Likewise, responses from the COM object are routed to the interop assembly and forwarded to
the .NET application. Each ArcGIS Engine control has events, properties, and methods that can be
accessed once embedded within a container, such as a .NET form. The objects and functionality in
each control can be combined with other ESRI ArcObjects and custom controls to create customized
end user applications.
The scenario has been written in both C# and Visual Basic .NET. Many developers will feel more
comfortable with Visual Basic .NET, as the code looks familiar to Visual Basic 6.0, while the syntax of
the C# programming language will be familiar to Java and C++ programmers. Whichever development
environment you use, your future success with the ArcGIS Engine controls depends on your skill in
both the programming environment and ArcObjects.
The MapControl, PageLayoutControl, TOCControl and ToolbarControl are used in this scenario to
provide the user interface of the application, and the LicenseControl is used to configure the
application with an appropriate license. The ArcGIS Engine controls are used in conjunction with other
ArcObjects and control commands by the developer to create a GIS map viewing application.
Design
The scenario has been designed to highlight how the ArcGIS Engine controls interact with each other
and to expose a part of each ArcGIS Engine control's object model to the developer.
Each .NET ArcGIS Engine control has a set of property pages that can be accessed once the control is
embedded in a .NET form. These property pages provide shortcuts to a selection of a control's
properties and methods and allow a developer to build an application without writing any code. This
scenario does not use the property pages but rather builds up the application programmatically.
The ArcGIS Engine controls and libraries used in this scenario are as follows:
ESRI.ArcGIS.ADF
ESRI.ArcGIS.AxControls
ESRI.ArcGIS.Carto
ESRI.ArcGIS.Controls
ESRI.ArcGIS.Display
ESRI.ArcGIS.Geometry
ESRI.ArcGIS.Output
ESRI.ArcGIS.System
ESRI.ArcGIS.SystemUI
The ESRI.ArcGIS.AxControls .NET Framework component represents each control that is hosted in
a .NET form, while the ESRI.ArcGIS.Controls assembly contains the object and interfaces from inside
each control's type library.
Implementation
The following implementation provides you with all the necessary code to successfully complete the
scenario. It does not provide step-by-step instructions to develop applications in Microsoft Visual
Studio .NET, as it assumes that you already have a working knowledge of the development
environment.
Loading the ArcGIS Engine controls
Before you start programming your application, the ArcGIS Engine controls and the other ArcGIS
Engine assembly references that the application will use should be loaded into the development
environment.
1.
Start Visual Studio .NET and create either a new Visual C# or Visual Basic Windows
Application project from the New Project dialog box.
2.
Name the project Controls and browse to a location to save the project.
3.
In the Toolbox click ArcGIS Windows Forms to display the ArcGIS Engine controls. If there
is no ArcGIS Windows Forms, right-click the Toolbox and click Choose Items from the
context menu.
4.
In the Choose Toolbox Items dialog box, click the .NET Framework Components tab and
check AxLicenseControl, AxMapControl, AxPageLayoutControl, AxTOCControl,
and AxToolbarControl, then click OK. The controls will now appear in the Toolbox. See the
following screen shot:
5.
6.
The ESRI .NET assemblies will be used to instantiate and make calls on the objects in the ESRI object
libraries from your C# or VB.NET project using the COM interoperability services provided by the .NET
Framework.
Embedding the ArcGIS Engine controls in a container
Before you can access each control's properties, methods, and events, each control needs embedding
in a .NET container. Once the controls are embedded in the form, they will shape the application's user
interface.
1.
2.
3.
4.
5.
6.
Resize and reposition each control on the form as shown in the following screen shot:
7.
Double-click the form to display the form's code window. Add using directives or import
statements in the following code example to the top of the code window:
In .NET a variable is fully-qualified using a namespace. Namespaces are a concept in .NET that allow
objects to be organized hierarchically, regardless of the assembly they are defined in. To make code
simpler and more readable, the directives act as shortcuts when referencing items specified in
namespaces.
If you start by typing ESRI., the autocompletion feature of IntelliSense allows you to complete the
next section of code by pressing the Tab key.
[C#]
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.SystemUI;
using
ESRI.ArcGIS.esriSystem;
Remember that C# is case sensitive. By default, when the project is created, C# will add some using
directives to some of the system namespaces.
License initialization using the LicenseControl
To successfully deploy this application on another machine, the application must configure a license.
First, it must check that a product license is available and second, it must initialize the product license.
If this license configuration fails, the application cannot run. License configuration can be performed
either by using the LicenseControl or by programmatically using the AoInitialize object. For the
purpose of this application, the LicenseControl will be used to handle license configuration.
When developing a stand-alone executable using ArcObjects, it is the responsibility of the application
to check and configure the licensing options. A license can be configured using either the
LicenseControl or the AoInitialize class and the IAoInitialize interface it implements, that is designed to
support license configuration. License initialization must be performed at application start time, before
any ArcObjects functionality is accessed. Failure to do so will result in application errors.
1.
2.
3.
Under Products, select the ArcGIS Engine check box and select Shutdown this application
if the selected licenses are not available check box, then click OK. See the following
screen shot:
The LicenseControl will appear on a form at design time so that it can be selected and its property
pages viewed. However, at run time the LicenseControl is invisible so its position on the form is
irrelevant.
This application can be initialized with an ArcGIS Engine license but you may optionally initialize the
application with a higher product license. For example, if you select the ArcGIS Engine license and the
ArcView license check boxes, the LicenseControl will initially try to initialize the application with an
ArcGIS Engine license (the lower license). If that license is not available, the LicenseControl will try to
initialize the application with an ArcView license (the next higher level license selected). If no product
licenses are available, then the application will fail to initialize.
In this application the LicenseControl will handle license initialization failure. If the application cannot
be initialized with an ArcGIS Engine product license, a License Failure dialog box appears before the
application is automatically shut down. Alternatively, a developer can handle license initialization
failure using the ILicenseControl interface members to obtain information on the nature of the failure
before the application is programmatically shut down.
Loading map documents into the PageLayoutControl and MapControl
Individual data layers or pre-authored map documents can be loaded into the MapControl and
PageLayoutControl. You can either load the sample map document that is provided or you can load
your own map document. Later, you will add a command to browse to a map document.
1.
Select the Form_Load event and enter the code in the following code example (you may
need to alter the relative path to the map document or substitute the file name if you are
using your own map document):
[C#]
privatevoid
MapViewer_Load(object
sender, System.EventArgs e)
{
//Load a pre-authored map
document into the
PageLayoutControl using
relative paths.
string fileName = @
"..\..\..\..\data\GulfOfStL
awrence\Gulf_of_St._Lawrenc
e.mxd";
if
(axPageLayoutControl1.Check
MxFile(fileName))
axPageLayoutControl1.LoadMx
File(fileName, "");
}
2.
Display the form in design mode and select axPageLayoutControl1 from the Properties
window and display the PageLayoutControl events. Double-click the
OnPageLayoutReplaced event to add an event handler to the code window. See the
following screen shot:
3.
[C#]
privatevoid
axPageLayoutControl1_OnPage
LayoutReplaced(object
sender,
IPageLayoutControlEvents_On
PageLayoutReplacedEvent e)
{
//Load the same preauthored map document into
the MapControl.
axMapControl1.LoadMxFile(ax
PageLayoutControl1.Document
Filename, null, null);
1.
In the Form_Load event, type the following code before the load document code:
[C#]
privatevoid
MapViewer_Load(object
sender, System.EventArgs e)
{
//Set buddy controls.
axTOCControl1.SetBuddyContr
ol(axPageLayoutControl1);
axToolbarControl1.SetBuddyC
ontrol(axPageLayoutControl1
);
}
Build and run the application. The map document is
loaded into the PageLayoutControl and the
TOCControl lists the data layers in the map
document. Use the TOCControl to toggle layer
visibility by selecting and deselecting the check
boxes. By default, the focus map of the map
document is loaded into the MapControl. At this
point, the ToolbarControl is empty because no
commands have been added to it. Try resizing the
form and note that the controls do not change size.
See the following screen shot:
1.
Display the form in design mode and select axPageLayoutControl1 from the Properties
window. Click the Anchor property and anchor the PageLayoutControl to the top, left,
bottom, and right of the form. See the following screen shot:
2.
Repeat to anchor the MapControl to the top, left, and bottom of the form. See the
following screen shot:
3.
Display the form in design mode and select the form from the Properties window and
display the form events. Double-click the ResizeBegin event to add an event handler to
the code window.
4.
In the Form_ResizeBegin event, enter the following code to draw a stretchy bitmap in
the PageLayoutControl and MapControl whenever the form is resized:
[C#]
privatevoid
MapViewer_ResizeBegin(objec
t sender, EventArgs e)
{
//Suppress data redraw and
draw bitmap instead.
axMapControl1.SuppressResiz
eDrawing(true, 0);
axPageLayoutControl1.Suppre
ssResizeDrawing(true, 0);
}
In the Form_ResizeEnd event, enter the following code to stop drawing a stretchy bitmap
in the PageLayoutControl and MapControl:
[C#]
privatevoid
MapViewer_ResizeEnd(object
sender, EventArgs e)
{
//Stop bitmap draw and draw
data.
axMapControl1.SuppressResiz
eDrawing(false, 0);
axPageLayoutControl1.Suppre
ssResizeDrawing(false, 0);
}
Build and run the application, then try to resize the
form.
Adding commands to the ToolbarControl
ArcGIS Engine comes with more than 230 commands and tools that work directly with the MapControl,
PageLayoutControl, and ToolbarControl. These commands and tools provide you with a lot of
frequently used GIS functionality for map navigation, map inquiry, graphics management, and feature
selection. In addition, there are commands and tools to work with the ArcGIS Engine extensions. You
will now add some of these commands and tools to your application to work with the
PageLayoutControl.
1.
[C#]
In the Form_Load event add the following code before the set buddy controls code:
privatevoid
MapViewer_Load(object
sender, EventArgs e)
{
//Add generic commands.
axToolbarControl1.AddItem("
esriControls.ControlsOpenDo
cCommand", - 1, - 1,
false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem("
esriControls.ControlsAddDat
aCommand", - 1, - 1,
false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
//Add page layout
navigation commands.
axToolbarControl1.AddItem("
esriControls.ControlsPageZo
omInTool", - 1, - 1,
true, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem("
esriControls.ControlsPageZo
omOutTool", - 1, - 1,
false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem("
esriControls.ControlsPagePa
nTool", - 1, - 1,
false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem("
esriControls.ControlsPageZo
omWholePageCommand", 1, - 1, false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
//Add map navigation
commands.
axToolbarControl1.AddItem("
esriControls.ControlsMapZoo
mInTool", - 1, - 1,
true, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem("
esriControls.ControlsMapZoo
mOutTool", - 1, - 1,
false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem("
esriControls.ControlsMapPan
Tool", - 1, - 1,
false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem("
esriControls.ControlsMapFul
lExtentCommand", - 1,
- 1, false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem(
"esriControls.ControlsMapZo
omToLastExtentBackCommand",
- 1, - 1, false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem(
"esriControls.ControlsMapZo
omToLastExtentForwardComman
d", - 1, - 1, false,
0,
esriCommandStyles.esriComma
ndStyleIconOnly);
//Add map inquiry commands.
axToolbarControl1.AddItem("
esriControls.ControlsMapIde
ntifyTool", - 1, - 1,
true, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem("
esriControls.ControlsMapFin
dCommand", - 1, - 1,
false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem("
esriControls.ControlsMapMea
sureTool", - 1, - 1,
false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
[C#]
publicpartialclass
MapViewer: Form
{
//The pop-up menu.
private IToolbarMenu
m_ToolbarMenu;
}
2.
Add the following code to the Form_Load event after the code, add the commands to the
ToolbarControl but before the set buddy controls code.
[C#]
privatevoid
MapViewer_Load(object
sender, EventArgs e)
{
//Add map inquiry commands.
1, false,
esriCommandStyles.esriComma
ndStyleIconAndText);
m_ToolbarMenu.AddItem("esri
Controls.ControlsPageZoomOu
tFixedCommand", - 1,
- 1, false,
esriCommandStyles.esriComma
ndStyleIconAndText);
m_ToolbarMenu.AddItem("esri
Controls.ControlsPageZoomWh
olePageCommand", - 1,
- 1, false,
esriCommandStyles.esriComma
ndStyleIconAndText);
m_ToolbarMenu.AddItem(
"esriControls.ControlsPageZ
oomPageToLastExtentBackComm
and", - 1, - 1,
true,
esriCommandStyles.esriComma
ndStyleIconAndText);
m_ToolbarMenu.AddItem(
"esriControls.ControlsPageZ
oomPageToLastExtentForwardC
ommand", - 1, - 1,
false,
esriCommandStyles.esriComma
ndStyleIconAndText);
}
Display the form in design mode, select
axPageLayoutControl1 from the Properties window,
and display the PageLayoutControl events. Doubleclick the OnMouseDown event to add an event
handler to the code window.
3.
[C#]
privatevoid
axPageLayoutControl1_OnMous
eDown(object sender,
IPageLayoutControlEvents_On
MouseDownEvent e)
{
//Pop-up the ToolbarMenu.
if (e.button == 2)
m_ToolbarMenu.PopupMenu(e.x
, e.y,
axPageLayoutControl1.hWnd);
}
Build and run the application. Right-click the
PageLayoutControl's display area to show the pop-up
menu and navigate around the page layout. See the
following screen shot:
Add the following code to the Form_Load event before the add commands to the
ToolbarMenu code.
[C#]
privatevoid
MapViewer_Load(object
sender, EventArgs e)
{
//Add map inquiry commands.
//Create a new
ToolbarPalette.
IToolbarPalette
toolbarPalette =
newToolbarPaletteClass();
//Add commands and tools to
the ToolbarPalette.
toolbarPalette.AddItem("esr
iControls.ControlsNewMarker
Tool", - 1, - 1);
toolbarPalette.AddItem("esr
iControls.ControlsNewLineTo
ol", - 1, - 1);
toolbarPalette.AddItem("esr
iControls.ControlsNewCircle
Tool", - 1, - 1);
toolbarPalette.AddItem("esr
iControls.ControlsNewEllips
eTool", - 1, - 1);
toolbarPalette.AddItem("esr
iControls.ControlsNewRectan
gleTool", - 1, - 1);
toolbarPalette.AddItem("esr
iControls.ControlsNewPolygo
nTool", - 1, - 1);
//Add the ToolbarPalette to
the ToolbarControl.
axToolbarControl1.AddItem(t
oolbarPalette, 0, - 1,
false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
1.
[C#]
privatevoid
MapViewer_Load(object
sender, EventArgs e)
{
//Set label editing to
manual.
axTOCControl1.LabelEdit =
esriTOCControlEdit.esriTOCC
ontrolManual;
}
2.
Display the form in design mode, select axTOCControl1 from the Properties window, and
display the TOCControl events. Double-click OnEndLabelEdit to add an event handler to
the code window.
3.
[C#]
privatevoid
axTOCControl1_OnEndLabelEdi
t(object sender,
ITOCControlEvents_OnEndLabe
lEditEvent e)
{
//If the new label is an
empty string, prevent the
edit.
if (e.newLabel.Trim() ==
"")
e.canEdit = false;
}
Build and run the application. To edit a map, layer,
heading, or legend class label in the TOCControl,
click it once, then click it a second time to invoke
1.
Add the following member variables to the class below the pop-up menu variable:
[C#]
publicpartialclass
MapViewer: Form
{
The variable declared as visBoundsUpdatedE is a delegate. A delegate is a class that can hold a
reference to a specific method and link it to a specific event. The linking process between the event
and the method is sometimes known in .NET as wiring.
2.
Create a new function called CreateOverviewSymbol. This is where you will create the
symbol used in the MapControl to represent the extent of the data in the focus map of
the PageLayoutControl. Add the following code to the function:
[C#]
privatevoid
CreateOverviewSymbol()
{
//Get the IRGBColor
interface.
IRgbColor color =
newRgbColorClass();
//Set the color properties.
color.RGB = 255;
//Get the ILine symbol
interface.
ILineSymbol outline =
newSimpleLineSymbolClass();
//Set the line symbol
properties.
outline.Width = 1.5;
outline.Color = color;
//Get the IFillSymbol
interface.
ISimpleFillSymbol
simpleFillSymbol =
newSimpleFillSymbolClass();
//Set the fill symbol
properties.
simpleFillSymbol.Outline
= outline;
simpleFillSymbol.Style =
esriSimpleFillStyle.esriSFS
Hollow;
m_FillSymbol =
simpleFillSymbol;
}
Call the CreateOverviewSymbol function from the
beginning of the Form_Load event. See the following
code example:
[C#]
privatevoid
MapViewer_Load(object
sender, EventArgs e)
{
//Create the symbol used on
the MapControl.
CreateOverviewSymbol();
}
Add the following OnVisibleBoundsUpdated function.
This function will be linked to an event raised when
the extent of the map is changed, and is used to set
the envelope to the new visible bounds of the map.
By refreshing the MapControl, you force it to redraw
the shape on its display.
[C#]
privatevoid
OnVisibleBoundsUpdated(IDis
playTransformation sender,
bool
sizeChanged)
{
//Set the extent to the new
visible extent.
m_Envelope =
sender.VisibleBounds;
//Refresh the MapControl's
foreground phase.
axMapControl1.ActiveView.Pa
rtialRefresh(esriViewDrawPh
ase.esriViewForeground,
null, null);
}
The default event interface of the PageLayoutControl
is the IPageLayoutControlEvents. These events do
not tell you when the extent of the map in a data
frame changes. To enable this functionality, use
the ITransformEvents interface of the
PageLayoutControl's focus map. Add the following
code to the
PageLayoutControl_OnPageLayoutReplaced event
handler before the load document code:
[C#]
privatevoid
axPageLayoutControl1_OnPage
LayoutReplaced(object
sender,
IPageLayoutControlEvents_On
PageLayoutReplacedEvent e)
{
//Get the IActiveView of
the focus map in the
PageLayoutControl.
IActiveView activeView =
axPageLayoutControl1.Active
View.FocusMap as
IActiveView;
//Trap the ITranformEvents
of the PageLayoutControl's
focus map.
visBoundsUpdatedE = new
ITransformEvents_VisibleBou
ndsUpdatedEventHandler
(OnVisibleBoundsUpdated);
IDisplayTransformation
displayTransformation =
activeView.ScreenDisplay.Di
splayTransformation;
//Start listening to the
transform events interface.
m_transformEvents =
(ITransformEvents_Event)dis
playTransformation;
//Start listening to the
VisibleBoundsUpdated method
on ITransformEvents
interface.
m_transformEvents.VisibleBo
undsUpdated +=
visBoundsUpdatedE;
//Get the extent of the
focus map.
m_Envelope =
activeView.Extent;
[C#]
privatevoid
axMapControl1_OnAfterDraw(o
bject sender,
IMapControlEvents2_OnAfterD
rawEvent e)
{
if (m_Envelope == null)
return ;
Navigating around the focus map using the map navigation tools will change the extent of the focus
map in the PageLayoutControl and cause the MapControl to update. Navigating around the page layout
with the page layout navigation tools will change the extent of the page layout (not the extent of the
focus map in the PageLayoutControl), so the MapControl will not update.
Creating a custom tool
Creating custom commands and tools to work with the MapControl and PageLayoutControl is very
similar to creating commands for the ESRI ArcMap application that you may have done previously. You
will create a custom tool that adds a text element containing today's date to the PageLayoutControl at
the location of a mouse click. However, you will create the command to work with the MapControl and
ToolbarControl, as well as the PageLayoutControl.
1.
2.
Choose the Class Library template from the ArcGIS Engine project types. Name the
project Commands and click OK.
3.
4.
5.
Choose Add New Item from the Project menu to add a new item to the Commands
project.
6.
Choose the Base Tool template from the ArcGIS Engine category in the Add New Item
dialog box.
7.
Name the tool AddDateTool and click Add to add it to the project.
8.
Click the ArcMap, MapControl, or PageLayoutControl Tool from the ArcGIS New Item
Wizard Options dialog box and click OK.
The AddDateTool class inherits from the ESRI BaseTool abstract class. Abstract classes are classes that
cannot be instantiated and frequently contain only partial implementation code or no implementation
at all. They are closely related to interfaces; however, they differ significantly from interfaces in that a
class may implement any number of interfaces but it can inherit from only one abstract class.
Inheriting the ESRI BaseCommand and BaseTool abstract classes will allow you to create commands
and tools more quickly and simply than directly implementing the esriSystemUI ICommand and ITool
interfaces.
The sealed class modifier in C# and the NotInheritable modifier in VB.NEt states that a class cannot be
inherited from. As this class is not designed for this purpose, it is prudent to add this modifier to
prevent other classes from inheriting this class.
9.
Add the following additional using directives or import statements to the class:
[C#]
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;
Update the code in the AddDateTool class constructor
as shown in the following code example:
The class constructor is a method that is called when the class is created. It can be used to set up
members of the class. In C# the constructor method has the same name as the class. It differs from
other methods in that it has no return type.
Instead of implementing the Bitmap, Caption, Category, Name, Message, and ToolTip methods
individually, you can set the values that should be returned from these methods and rely on the
BaseTool class to provide the implementation for these methods. The other members will be left to
return the default values as implemented by the BaseTool class.
[C#]
public AddDateTool()
{
base.m_category =
"CustomMapViewer";
base.m_caption = "Add
Date";
base.m_message = "Adds a
date element to the active
view";
base.m_toolTip = "Add
Date";
base.m_name =
"CustomMapViewer_AddDateToo
l";
try
{
string bitmapResourceName =
GetType().Name + ".bmp";
base.m_bitmap =
newBitmap(GetType(),
bitmapResourceName);
base.m_cursor =
newCursor(GetType(),
GetType().Name + ".cur");
}
catch (Exception ex)
{
System.Diagnostics.Trace.Wr
iteLine(ex.Message,
"Invalid Bitmap");
}
}
Navigate to the overridden OnCreate method and
look at the code.
The ICommand.OnCreate method is passed a handle or hook to the application that the command will
work with. In this case, it can be a MapControl, PageLayoutControl, ToolbarControl, or the ArcMap
application. Rather than adding code into the OnCreate method to determine the type of hook that is
being passed to the command, the HookHelper is used to handle this. A command or tool needs to
know how to handle the hook it gets passed, so a check is needed to determine the type of ArcGIS
Engine control that has been passed. The HookHelper is used to hold the hook and return the
ActiveView regardless of the type of hook (in this case a MapControl, PageLayoutControl,
ToolbarControl, or ArcMap).
12. Navigate to the overridden OnMouseDown event and add the following code:
[C#]
publicoverridevoid
OnMouseDown(int Button, int
Shift, int X, int Y)
{
//Get the active view.
IActiveView activeView =
m_hookHelper.ActiveView;
textElement.Text =
DateTime.Now.ToShortDateStr
ing();
ArcGIS Engine expects a custom command or tool to be a COM class; therefore, the .NET class you
have created must be exposed as a COM class by creating a COM callable wrapper for it. The BaseTool
has already provided the attributes and globally unique identifiers (GUIDs) required by COM in
the class.
The Commands project properties have also been automatically amended to set Register for COM
Interop to true. Setting the Register for COM Interop property to true will invoke the Assembly
Registration tool (Regasm.exe). This will add the information about the class to the registry that a
COM client would expect to find.
Visual Studio .NET provides the ability to specify functions that execute when an assembly exposed for
COM interop is registered and unregistered on a system. This allows you to register your class in a
component category that the Customize dialog box will look for. The BaseTool has already provided
these COM Registration Functions in the class and will register the tool with the ESRI Controls
Commands and ESRI Mx Commands component categories. The ComVisible attribute is set to false to
ensure that this method cannot be called directly by a COM client. It does not affect the method being
called when the assembly is registered with COM.
13. Build the Commands project.
14. In the Controls Windows Application project that you created at the beginning of this
scenario, add the following code before the ToolbarPalette code:
[C#]
privatevoid
MapViewer_Load(object
sender, EventArgs e)
{
//Add map inquiry commands.
//Create a new
ToolbarPalette.
}
[C#]
publicpartialclass
MapViewer: Form
{
privatevoid
CreateCustomizeDialog()
{
//Create a new Customize
dialog box.
m_CustomizeDialog =
newCustomizeDialogClass();
//Set the title.
m_CustomizeDialog.DialogTit
le = "Customize
ToolbarControl Items";
//Show the Add from File
button.
m_CustomizeDialog.ShowAddFr
omFile = true;
//Set the ToolbarControl
that new items will be
added to.
m_CustomizeDialog.SetDouble
ClickDestination(axToolbarC
ontrol1);
ent)m_CustomizeDialog).OnCl
oseDialog +=
closeDialogE;
}
Call the CreateCustomizeDialog function from the
beginning of the Form_Load event. See the following
code example:
[C#]
privatevoid
MapViewer_Load(object
sender, EventArgs e)
{
//Create the Customize
dialog box for the
ToolbarControl.
CreateCustomizeDialog();
Display the form in design mode and select chkCustomize from the Properties window
and display the chkCustomize events. Double-click CheckedChanged to add an event
handler to the code window.
5.
[C#]
privatevoid
chkCustomize_CheckedChanged
(object sender, EventArgs
e)
{
//Show or hide the
Customize dialog box.
if (chkCustomize.Checked ==
false)
m_CustomizeDialog.CloseDial
og();
else
m_CustomizeDialog.StartDial
og(axToolbarControl1.hWnd);
}
ontrol1.hWnd)
EndIf
EndSub
7.
Add the following OnStartDialog and OnCloseDialog event handlers. These functions will
be wired to events raised whenever the Customize dialog box is opened or closed.
[C#]
privatevoid OnStartDialog()
{
axToolbarControl1.Customize
= true;
}
privatevoid OnCloseDialog()
{
axToolbarControl1.Customize
= false;
chkCustomize.Checked =
false;
}
Build and run the application. Check the
Customize control to put the ToolbarControl into
customize mode and to open the Customize dialog
box.
8.
On the Commands tab select the Graphic Element category and double-click the Select
Elements command to add it to the ToolbarControl. Right-click an item on the
ToolbarControl to adjust its appearance in terms of style and grouping. See the following
screen shot:
10. Stop customizing the application. Use the select tool to move the text element containing
today's date.
Saving and loading ToolbarControl items
The contents of a ToolbarControl can be persisted into a user's profile when an application exits to
preserve any customizations made to the ToolbarControl by the end user. An application can load the
persisted contents back into the ToolbarControl at application start time. You will persist the contents
of the ToolbarControl into a file located in the same directory as the applications executing assembly.
1.
Create a new function called SaveToolbarControlItems. This is where you will persist the
contents of the ToolbarControl by adding the following code to the function:
[C#]
privatevoid
SaveToolbarControlItems(str
ing filePath)
{
//Create a
MemoryBlobStream.
IBlobStream blobStream =
newMemoryBlobStreamClass();
//Get the IStream
interface.
IStream stream =
blobStream;
//Save the ToolbarControl
into the stream.
axToolbarControl1.SaveItems
(stream);
//Save the stream to a
file.
blobStream.SaveToFile(fileP
ath);
}
privatevoid
LoadToolbarControlItems(str
ing filePath)
{
//Create a
MemoryBlobStream.
IBlobStream blobStream =
newMemoryBlobStreamClass();
//Get the IStream
interface.
IStream stream =
blobStream;
//Load the stream from the
file.
blobStream.LoadFromFile(fil
ePath);
//Load the stream into the
ToolbarControl.
axToolbarControl1.LoadItems
(stream);
}
3.
Display the form in design mode and select the form from the Properties window and
display the form events. Double-click the FormClosing event to add an event handler to
the code window.
4.
In the FormClosing event, enter the following code to persist the contents of the
ToolbarControl into a file at the same location as the executing assembly. You may need
to substitute "Controls.exe" with the name of your executable.
[C#]
privatevoid
MapViewer_FormClosing(objec
t sender,
FormClosingEventArgs e)
{
//Get file name to persist
the ToolbarControl.
String filePath =
System.Reflection.Assembly.
GetExecutingAssembly()
.Location.Replace("Controls
.exe", "") +
@"\PersistedItems.txt";
//Persist ToolbarControl
contents.
SaveToolbarControlItems(fil
ePath);
}
5.
Update the code to add items to the ToolbarControl in the Form_Load event as shown in
the following code (you may need to substitute "Controls.exe" with the name of your
executable):
[C#]
if
(System.IO.File.Exists(file
Path))
LoadToolbarControlItems(fil
ePath);
else
{
//Add generic commands.
axToolbarControl1.AddItem("
esriControls.ControlsOpenDo
cCommand", - 1, - 1,
false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem("
esriControls.ControlsAddDat
aCommand", - 1, - 1,
false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
//Add page layout
navigation commands.
axToolbarControl1.AddItem("
esriControls.ControlsPageZo
omInTool", - 1, - 1,
true, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem("
esriControls.ControlsPageZo
omOutTool", - 1, - 1,
false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem("
esriControls.ControlsPagePa
nTool", - 1, - 1,
false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem("
esriControls.ControlsPageZo
omWholePageCommand", 1, - 1, false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
//Add map navigation
commands.
axToolbarControl1.AddItem("
esriControls.ControlsMapZoo
mInTool", - 1, - 1,
true, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem("
esriControls.ControlsMapZoo
mOutTool", - 1, - 1,
false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem("
esriControls.ControlsMapPan
Tool", - 1, - 1,
false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem("
esriControls.ControlsMapFul
lExtentCommand", - 1,
- 1, false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem(
"esriControls.ControlsMapZo
omToLastExtentBackCommand",
- 1, - 1, false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem(
"esriControls.ControlsMapZo
omToLastExtentForwardComman
d", - 1, - 1, false,
0,
esriCommandStyles.esriComma
ndStyleIconOnly);
//Add map inquiry commands.
axToolbarControl1.AddItem("
esriControls.ControlsMapIde
ntifyTool", - 1, - 1,
true, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem("
esriControls.ControlsMapFin
dCommand", - 1, - 1,
false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
axToolbarControl1.AddItem("
esriControls.ControlsMapMea
sureTool", - 1, - 1,
false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
//Add custom AddDateTool.
axToolbarControl1.AddItem("
Commands.AddDateTool", 1, - 1, false, 0,
esriCommandStyles.esriComma
ndStyleIconAndText);
//Create a new
ToolbarPalette.
IToolbarPalette
toolbarPalette =
newToolbarPaletteClass();
//Add commands and tools to
the ToolbarPalette.
toolbarPalette.AddItem("esr
iControls.ControlsNewMarker
Tool", - 1, - 1);
toolbarPalette.AddItem("esr
iControls.ControlsNewLineTo
ol", - 1, - 1);
toolbarPalette.AddItem("esr
iControls.ControlsNewCircle
Tool", - 1, - 1);
toolbarPalette.AddItem("esr
iControls.ControlsNewEllips
eTool", - 1, - 1);
toolbarPalette.AddItem("esr
iControls.ControlsNewRectan
gleTool", - 1, - 1);
toolbarPalette.AddItem("esr
iControls.ControlsNewPolygo
nTool", - 1, - 1);
//Add the ToolbarPalette to
the ToolbarControl.
axToolbarControl1.AddItem(t
oolbarPalette, 0, - 1,
false, 0,
esriCommandStyles.esriComma
ndStyleIconOnly);
}
Build and run the application and customize the
ToolbarControl.
6.
7.
Restart the application. The customizations you made to the ToolbarControl will be
reflected in the application.
1.
Display the form in design mode and select MenuStrip control on the form.
2.
3.
On the File menu click Type Here and type Print to create a menu item.
4.
Double click the Print menu item to add an event handler to the code window.
5.
In the PrintToolStripMenuItem_Click event, enter the following code to send the page to
the printer:
[C#]
privatevoid
printToolStripMenuItem_Clic
k(object sender, EventArgs
e)
{
//Exit if there is no
system default printer.
if
(axPageLayoutControl1.Print
er == null)
{
MessageBox.Show("Unable to
print!", "No default
printer");
return ;
}
esriPageToPrinterMapping.es
riPageMappingScale;
//Send the page layout to
the printer.
axPageLayoutControl1.PrintP
ageLayout();
}
6.
Build and run the application. Use the Print menu item to send output to the printer.
See the following screen shot:
Deployment
To successfully deploy this application on a user's machine:
The application's executable and the .dll and .tlb files containing the custom command
will need to be deployed on the user's machine. The Assembly Registration tool
(RegAsm.exe) must be used to add information about the custom class to the registry.
The user's machine will need an installation of the ArcGIS Engine Runtime and a standard
ArcGIS Engine license.
The user's machine will need an installation of the Microsoft .NET Framework 2.0.
Additional resources
The following resources may help you understand and apply the concepts and techniques presented in
this scenario:
Additional documentation is available in the ArcGIS Engine SDK for the Microsoft .NET
Framework. This includes component help, object model diagrams, and samples to help
you get started.
ESRI Developer Network (EDN) Web site provides the most up-to-date information for
ArcGIS developers including updated samples and technical
documents. See http://edn.esri.com.
ESRI online discussion forums provide invaluable assistance from other ArcGIS
developers. See http://support.esri.com and click the User Forums tab.
Microsoft documentation is also available for the Visual Studio .NET development
environment. See http://msdn.com.