ArcGIS Engine 的插件式开发

我们经常做AE开发时,我们可以选择常规开发,也可以选择插件式开发,而插件式开发的特点是可以重复使用。如果选择C#开发,两种方式的唯一区别就是前者可以一拖控件的方式开发,而后者全都得手动实现。

在ArcGIS Engine API中有两个接口,ITool 和 ICommand,做插件式开发时,我们可以继承它们,但是,抽象类BaseComman和BaseTool分别实现了这两个接口,所以我们可以直接继承该抽象类。

我用的是ArcGIS Engine 10 和 VS2008,并且,我用到了DotnetBar95.实现一个command命令,点击时弹出一个对话框,选择当前地图的一个图层,点击确定将缩放至图层。效果如下:

 

第一步:新建一个AE类库工程。

  

完成后,类所在的GUID已经自动生成,

第二步:添加所需要的.net类库,DotnetBar和AE类库并用using引用进当前类:

using System.Windows.Forms;
using DevComponents.DotNetBar;
using DevComponents.Instrumentation.Design;
using DevComponents.DotNetBar.Controls;
using System.Drawing;

using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.ADF.CATIDs;

第三步:因为BaseComman类是一个抽象类,所以得实现它的抽象方法,其实就有一个抽象方法OnCreate(object hook){},这也是定制命令中最重要的一个方法,是将插件和宿主程序连接的桥梁。添加此方法:

public override void OnCreate(object hook)
{

}

第四步:定义需要的私有变量:

 //当前地图对象
IMapControlDefault map;

//命令窗口
private Office2007Form form;

//完成命令按钮
private ButtonX btnOk;

//完成命令按钮
private ButtonX btnCancel;

//涂层了列表框
private ComboBoxEx layerListCombo;

//图层选择提示标签
private LabelX layerLabel;

第四步:创建无参数构造方法,初始化变量,如命令标题,提示信息,图标等。

1  public Class1(){
2
3 base.m_caption = "test";
4 base.m_toolTip = "demo";
5 base.m_name = "zoomToLayer";
6 //...
7
8 }

第五步:完成插件与宿主的关联,这也是插件式开发最关键的一步,这一步完成了,就和我们一般AE的开发没什么区别了。

1 public override void OnCreate(object hook)
2 {
3 if(hook is IToolbarControl)
4 {
5 IToolbarControl toolbarCtl = (IToolbarControl)hook;
6 map = (IMapControlDefault)toolbarCtl.Buddy;
7 }
8 }

第六步:完成各个自定义控件的初始化函数(函数自定义)。

 1 /初始化自定义函数
2 public void CustomCtlInitial()
3 {
4 form = new Office2007Form();
5 btnOk = new ButtonX();
6 btnCancel = new ButtonX();
7 layerListCombo = new ComboBoxEx();
8 layerLabel = new LabelX();
9
10 form.ClientSize = new System.Drawing.Size(283, 287);
11 btnOk.Size = new System.Drawing.Size(75, 23);
12 btnCancel.Size = new System.Drawing.Size(75, 23);
13 layerListCombo.Size = new System.Drawing.Size(164, 21);
14 layerLabel.Size = new System.Drawing.Size(97, 23);
15
16 btnOk.Location = new System.Drawing.Point(52, 215);
17 btnCancel.Location = new System.Drawing.Point(161, 215);
18 layerListCombo.Location = new System.Drawing.Point(62, 89);
19 layerLabel.Location = new System.Drawing.Point(111, 48);
20
21 form.Text = "缩放至图层";
22 btnOk.Text = "完成";
23 btnCancel.Text = "取消";
24 layerListCombo.Text = "<当前图层列表>";
25 layerLabel.Text = "请选择图层:";
26
27 btnOk.Click += new System.EventHandler(this.btnOk_Click);
28 btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
29
30 form.Controls.Add(btnOk);
31 form.Controls.Add(btnCancel);
32 form.Controls.Add(layerListCombo);
33 form.Controls.Add(layerLabel);
34 }

第七步:完成确定和取消按钮的点击事件:

 1 private void btnOk_Click(object sender, EventArgs e)
2 {
3 int selLayerIndex = layerListCombo.SelectedIndex;
4 IFeatureLayer featureLayer = map.get_Layer(selLayerIndex) as IFeatureLayer;
5 IEnvelope envelop = featureLayer.AreaOfInterest;
6 map.Extent = envelop;
7 map.ActiveView.Refresh();
8 this.form.Close();
9
10 }
11 private void btnCancel_Click(object sender, EventArgs e)
12 {
13 this.form.Close();
14 }

第八步:加载当前地图的图层到列表中:

public void addLayerToComb()
{
int layerCount = map.LayerCount;
String layerName;
for (int i = 0; i < layerCount; i++)
{
IFeatureLayer featureLayer = map.get_Layer(i) as IFeatureLayer;
layerName = featureLayer.Name;
layerListCombo.Items.Add(layerName);
}
}

第九步:覆写BaseComman的Onclick方法:

1  public override void OnClick()
2 {
3 CustomCtlInitial();
4 addLayerToComb();
5
6 form.Show();
7 }


第十步:在类的最前面加上AE注册与反注册的代码,这个是固定的代码,从AE api中可以找到。

 1 #region COM Registration Function(s)
2 [ComRegisterFunction()]
3 [ComVisible(false)]
4 static void RegisterFunction(Type registerType)
5 {
6 // Required for ArcGIS Component Category Registrar support
7 ArcGISCategoryRegistration(registerType);
8 }
9
10 [ComUnregisterFunction()]
11 [ComVisible(false)]
12 static void UnregisterFunction(Type registerType)
13 {
14 // Required for ArcGIS Component Category Registrar support
15 ArcGISCategoryUnregistration(registerType);
16 }
17
18 #region ArcGIS Component Category Registrar generated code
19 /// <summary>
20 /// Required method for ArcGIS Component Category registration -
21 /// Do not modify the contents of this method with the code editor.
22 /// </summary>
23 private static void ArcGISCategoryRegistration(Type registerType)
24 {
25 string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
26 ControlsCommands.Register(regKey);
27 }
28 /// <summary>
29 /// Required method for ArcGIS Component Category unregistration -
30 /// Do not modify the contents of this method with the code editor.
31 /// </summary>
32 private static void ArcGISCategoryUnregistration(Type registerType)
33 {
34 string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
35 ControlsCommands.Unregister(regKey);
36 }
37
38 #endregion
39 #endregion

第十一步:编译程序,将生成的类型库在在到应用程序的toolbarControl控件中即可使用。

完整代码:

  1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Runtime.InteropServices;
5
6 using System.Windows.Forms;
7 using DevComponents.DotNetBar;
8 using DevComponents.Instrumentation.Design;
9 using DevComponents.DotNetBar.Controls;
10 using System.Drawing;
11
12 using ESRI.ArcGIS.SystemUI;
13 using ESRI.ArcGIS.ADF.BaseClasses;
14 using ESRI.ArcGIS.Controls;
15 using ESRI.ArcGIS.Carto;
16 using ESRI.ArcGIS.Geometry;
17 using ESRI.ArcGIS.ADF.CATIDs;
18
19
20 namespace plugin02
21 {
22 [Guid("159BC969-7AFF-44d6-821E-C851D62C63F3")]
23 [ClassInterface(ClassInterfaceType.None)]
24 [ProgId("plugin02.Class1")]
25 public class Class1 : BaseCommand
26 {
27 #region COM Registration Function(s)
28 [ComRegisterFunction()]
29 [ComVisible(false)]
30 static void RegisterFunction(Type registerType)
31 {
32 // Required for ArcGIS Component Category Registrar support
33 ArcGISCategoryRegistration(registerType);
34 }
35
36 [ComUnregisterFunction()]
37 [ComVisible(false)]
38 static void UnregisterFunction(Type registerType)
39 {
40 // Required for ArcGIS Component Category Registrar support
41 ArcGISCategoryUnregistration(registerType);
42 }
43
44 #region ArcGIS Component Category Registrar generated code
45 /// <summary>
46 /// Required method for ArcGIS Component Category registration -
47 /// Do not modify the contents of this method with the code editor.
48 /// </summary>
49 private static void ArcGISCategoryRegistration(Type registerType)
50 {
51 string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
52 ControlsCommands.Register(regKey);
53 }
54 /// <summary>
55 /// Required method for ArcGIS Component Category unregistration -
56 /// Do not modify the contents of this method with the code editor.
57 /// </summary>
58 private static void ArcGISCategoryUnregistration(Type registerType)
59 {
60 string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
61 ControlsCommands.Unregister(regKey);
62 }
63
64 #endregion
65 #endregion
66
67
68
69
70
71 //当前地图对象
72 IMapControlDefault map;
73
74 //命令窗口
75 private Office2007Form form;
76
77 //完成命令按钮
78 private ButtonX btnOk;
79
80 //完成命令按钮
81 private ButtonX btnCancel;
82
83 //涂层了列表框
84 private ComboBoxEx layerListCombo;
85
86 //图层选择提示标签
87 private LabelX layerLabel;
88
89 public Class1(){
90
91
92
93 base.m_caption = "test";
94 base.m_toolTip = "demo";
95 base.m_name = "zoomToLayer";
96
97 }
98
99 public override void OnCreate(object hook)
100 {
101 if(hook is IToolbarControl)
102 {
103 IToolbarControl toolbarCtl = (IToolbarControl)hook;
104 map = (IMapControlDefault)toolbarCtl.Buddy;
105 }
106 }
107
108 public override void OnClick()
109 {
110 CustomCtlInitial();
111 addLayerToComb();
112
113 form.Show();
114 }
115
116 //初始化自定义函数
117 public void CustomCtlInitial()
118 {
119 form = new Office2007Form();
120 btnOk = new ButtonX();
121 btnCancel = new ButtonX();
122 layerListCombo = new ComboBoxEx();
123 layerLabel = new LabelX();
124
125 form.ClientSize = new System.Drawing.Size(283, 287);
126 btnOk.Size = new System.Drawing.Size(75, 23);
127 btnCancel.Size = new System.Drawing.Size(75, 23);
128 layerListCombo.Size = new System.Drawing.Size(164, 21);
129 layerLabel.Size = new System.Drawing.Size(97, 23);
130
131 btnOk.Location = new System.Drawing.Point(52, 215);
132 btnCancel.Location = new System.Drawing.Point(161, 215);
133 layerListCombo.Location = new System.Drawing.Point(62, 89);
134 layerLabel.Location = new System.Drawing.Point(111, 48);
135
136 form.Text = "缩放至图层";
137 btnOk.Text = "完成";
138 btnCancel.Text = "取消";
139 layerListCombo.Text = "<当前图层列表>";
140 layerLabel.Text = "请选择图层:";
141
142 btnOk.Click += new System.EventHandler(this.btnOk_Click);
143 btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
144
145 form.Controls.Add(btnOk);
146 form.Controls.Add(btnCancel);
147 form.Controls.Add(layerListCombo);
148 form.Controls.Add(layerLabel);
149 }
150
151 private void btnOk_Click(object sender, EventArgs e)
152 {
153 int selLayerIndex = layerListCombo.SelectedIndex;
154 IFeatureLayer featureLayer = map.get_Layer(selLayerIndex) as IFeatureLayer;
155 IEnvelope envelop = featureLayer.AreaOfInterest;
156 map.Extent = envelop;
157 map.ActiveView.Refresh();
158 this.form.Close();
159
160 }
161 private void btnCancel_Click(object sender, EventArgs e)
162 {
163 this.form.Close();
164 }
165
166 public void addLayerToComb()
167 {
168 int layerCount = map.LayerCount;
169 String layerName;
170 for (int i = 0; i < layerCount; i++)
171 {
172 IFeatureLayer featureLayer = map.get_Layer(i) as IFeatureLayer;
173 layerName = featureLayer.Name;
174 layerListCombo.Items.Add(layerName);
175 }
176 }
177
178 }
179 }







 

  




 



 

posted @ 2012-04-06 06:22  地理小子  阅读(1807)  评论(0编辑  收藏  举报