ArcGIS Engine入门教程_第六章_实现右键菜单

6
分享 2016-03-11
1.实现右键菜单栏

下面我们看下比较常用的右键菜单栏如何实现。
1. 在VS2013的工具箱中,展开Menus & Toolbars,双击ContextMenuStrip控件,这样就在窗体上添加了一个上下文菜单。



2. 在该上下文菜单中添加“Remove Layer”和“Open AttributeTable”菜单项。



3. 下面我们添加代码来实现这两个功能。通过操作Desktop我们知道,在图层处右击会弹出上下文菜单,Remove Layer和Open AttributeTable都是针对所选图层来操作的,那么Engine中如何得到鼠标右击TocControl时选择的图层呢?ITOCControl.HitTest方法为我们提供了便利。首先添加axTOCControl1的OnMouseDown事件。选中窗体上的axTOCControl1,双击添加OnMouseDown事件。



4. 声明pGlobeLayer为全局变量,private ILayer pGlobeLayer = null;然后在OnMouseDown事件中添加如下代码。
private void axTOCControl1_OnMouseDown(object sender, ESRI.ArcGIS.Controls.ITOCControlEvents_OnMouseDownEvent e)
{
if (axMapControl1.LayerCount > 0)
{
esriTOCControlItem pItem = new esriTOCControlItem();
//pGlobeLayer为全局变量
pGlobeLayer = new FeatureLayerClass();
IBasicMap pBasicMap = new MapClass();
object pOther = new object();
object pIndex = new object();
//获取点击的位置
axTOCControl1.HitTest(e.x, e.y, ref pItem, ref pBasicMap, ref pGlobeLayer, ref pOther, ref pIndex);
//点击的是Layer的话,则弹出上下文菜单
if (e.button == 2 && pItem == esriTOCControlItem.esriTOCControlItemLayer)
{
contextMenuStrip1.Show(axTOCControl1, e.x, e.y);
}
}
}


5. 这时右击图层会弹出该上下文菜单,接下来我们编写代码来分别实现“Remove Layer”和“Open AttributeTable”功能。



6. 在设计界面左下角点击contextMenuStrip1,弹出的菜单中双击“Remove Layer”,添加其Click事件。



7. 在“Remove Layer”的Click事件中添加如下代码。
private void removeLayerToolStripMenuItem_Click(object sender, EventArgs e)
{
if (axMapControl1.LayerCount > 0)
{
if (pGlobeLayer != null)
{
axMapControl1.Map.DeleteLayer(pGlobeLayer);
}
}
}


8. 下面我们实现“Open AttributeTable”的功能,相比“Remove Layer”,其实现会相对复杂一些。首先还是添加其Click事件,方法同上,然后需要新建窗体用来显示属性表。具体为选中该工程右击,下拉列表中选择Add->Windows Form,为其窗体命名为“AttributeTable”,点击“Add”。





9. 打开该新建窗体,在工具包中选择DataGridView双击添加到窗体中,然后选中该DataGridView,设置其Dock选项为Fill。



10. 下面我们开始编写代码,在AttributeTable.cs 源代码顶部添加如下代码,导入命名空间。
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;


11. 在窗体类中添加如下代码。
private IFeatureLayer pFeatureLayer = null;
public AttributeTable(IFeatureLayer _FeatureLayer)
{
InitializeComponent();
pFeatureLayer = _FeatureLayer;
}


12. 为窗体的Load事件添加代码。该事件处理主要是从图层中读取要素类的属性信息,并且显示到DataGridView控件中。
private void AttributeTable_Load(object sender, EventArgs e)
{
IFields pFields;
pFields = pFeatureLayer.FeatureClass.Fields;
dataGridView1.ColumnCount = pFields.FieldCount;
for (int i = 0; i < pFields.FieldCount; i++)
{
string fldName = pFields.get_Field(i).Name;
dataGridView1.Columns.Name = fldName;
dataGridView1.Columns.ValueType = System.Type.GetType(ParseFieldType(pFields.get_Field(i).Type));
}
IFeatureCursor pFeatureCursor;
pFeatureCursor = pFeatureLayer.FeatureClass.Search(null, false);
IFeature pFeature;
pFeature = pFeatureCursor.NextFeature();
while (pFeature != null)
{
string fldValue = new string[pFields.FieldCount];
for (int i = 0; i < pFields.FieldCount; i++)
{
string fldName;
fldName = pFields.get_Field(i).Name;
if (fldName == pFeatureLayer.FeatureClass.ShapeFieldName)
{
fldValue = Convert.ToString(pFeature.Shape.GeometryType);
}
else
fldValue = Convert.ToString(pFeature.get_Value(i));
}
dataGridView1.Rows.Add(fldValue);
pFeature = pFeatureCursor.NextFeature();
}
}
[i][i][i]添加下面函数进行类型转换。[/i][/i][/i]
private string ParseFieldType(esriFieldType TableFieldType)
{
switch (TableFieldType)
{
case esriFieldType.esriFieldTypeBlob:
return "System.String";
case esriFieldType.esriFieldTypeDate:
return "System.DateTime";
case esriFieldType.esriFieldTypeDouble:
return "System.Double";
case esriFieldType.esriFieldTypeGeometry:
return "System.String";
case esriFieldType.esriFieldTypeGlobalID:
return "System.String";
case esriFieldType.esriFieldTypeGUID:
return "System.String";
case esriFieldType.esriFieldTypeInteger:
return "System.Int32";
case esriFieldType.esriFieldTypeOID:
return "System.String";
case esriFieldType.esriFieldTypeRaster:
return "System.String";
case esriFieldType.esriFieldTypeSingle:
return "System.Single";
case esriFieldType.esriFieldTypeSmallInteger:
return "System.Int32";
case esriFieldType.esriFieldTypeString:
return "System.String";
default:
return "System.String";
}
}


13. 在Form1.cs的OpenAttributeTable的Click事件中添加代码。
private void openAttributeTableToolStripMenuItem_Click(object sender, EventArgs e)
{
AttributeTable pAttributeTable = new AttributeTable(pGlobeLayer as IFeatureLayer);
pAttributeTable.Show();
}

14. 在键盘上按F5启动调试。添加continent.shp文件到地图控件中,然后选中该图层,在弹出的上下文菜单中选择“Open AttributeTable”菜单项,即弹出属性表。




本教程各章节连接:
ArcGIS Engine入门教程_第一章_引言: http://zhihu.esrichina.com.cn/?/article/532
ArcGIS Engine入门教程_第二章_类库介绍: http://zhihu.esrichina.com.cn/?/article/533
ArcGIS Engine入门教程_第三章_软件安装: http://zhihu.esrichina.com.cn/?/article/534
ArcGIS Engine入门教程_第四章_创建Engine应用程序: http://zhihu.esrichina.com.cn/?/article/535
ArcGIS Engine入门教程_第五章_添加数据: http://zhihu.esrichina.com.cn/?/article/536
ArcGIS Engine入门教程_第六章_实现右键菜单: http://zhihu.esrichina.com.cn/?/article/537

 

7 个评论

很棒,希望能增加更多的功能,教教大家实现鹰眼功能什么的(^\||/^)
写得真好,继续等待更新
写得真好,继续等待更新
程序中部分设计中括号的部分代码缺失,可以参考下面的代码:
……
dataGridView1.Columns[i].Name = fldName;
dataGridView1.Columns[i].ValueType = System.Type.GetType(ParseFieldType(pFields.get_Field(i).Type));
……
……
string [] fldValue = new string[pFields.FieldCount];
……
fldValue[i] = Convert.ToString(pFeature.Shape.GeometryType);
……
fldValue[i] = Convert.ToString(pFeature.get_Value(i));
……
写的挺好的,四楼的代码修改的很有水平,我抄代码的时候忘记了这些,感谢!
鹰眼功能在ArcEngine的原版代码里有
第11步只是将AttributeTable函数进行改写,而不是在后面添加。写的真好,期待更新

要回复文章请先登录注册