在 ArcGIS Engine(AE)中实现属性数据表查询显示,可按照以下步骤进行操作,并配合相应的代码实现:
步骤一:创建项目及界面设置
- 新建项目:在 Visual Studio 中创建一个 Windows Forms Application 项目。
- 添加控件:从工具箱中拖一个
DataGridView
控件到窗体上,并将其Dock
属性设置为Fill
,以便它能填满整个窗体。该控件用于显示属性数据表。
步骤二:引用相关程序集
在项目中添加对 ArcGIS Engine 相关程序集的引用,主要包括:
-
打开引用管理界面
- 打开你的项目,在右侧 “解决方案资源管理器” 中找到项目下的 “引用” 文件夹。
- 右键点击 “引用”,选择 “添加引用”。
-
添加 ArcGIS Engine 程序集
- 在弹出的 “引用管理器” 窗口中,点击左侧的 “浏览”。
- 导航到 ArcGIS Engine 的安装目录(以常见安装路径为例):
- 64 位系统:
C:\Program Files\ArcGIS\Engine\Bin
- 32 位系统:
C:\Program Files (x86)\ArcGIS\Engine\Bin
- 64 位系统:
- 按住
Ctrl
键,依次选中以下文件:ESRI.ArcGIS.Carto.dll
ESRI.ArcGIS.Controls.dll
ESRI.ArcGIS.Geodatabase.dll
ESRI.ArcGIS.esriSystem.dll
- 点击 “确定”,完成程序集引用添加。
步骤三:根据图层获取属性表结构(代码实现)
-
打开代码编辑窗口
- 在 “解决方案资源管理器” 中,双击包含窗体逻辑的代码文件(如
Form1.cs
),进入代码编辑界面。
- 在 “解决方案资源管理器” 中,双击包含窗体逻辑的代码文件(如
-
添加命名空间引用
- 在代码文件顶部,确保已有(若无则添加)以下命名空间引用:
using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Geodatabase; using System.Data;
- 在代码文件顶部,确保已有(若无则添加)以下命名空间引用:
通过传入的ILayer
对象,查询到对应的ITable
对象,再从ITable
的Fields
中获取每个IField
,然后根据IField
设置DataTable
的DataColumn
,从而创建一个只包含图层字段的空DataTable
。GeoDatabase 的数据类型与.NET 的数据类型不同,因此需要进行转换。示例代码如下:
- 编写获取属性表结构的方法
- 在窗体类(如
public partial class Form1 : Form
)内部,添加以下代码:
- 在窗体类(如
private DataTable CreateEmptyDataTable(ILayer layer)
{
DataTable dataTable = new DataTable();
IFeatureLayer featureLayer = layer as IFeatureLayer;
if (featureLayer != null)
{
ITable table = featureLayer.FeatureClass as ITable;
if (table != null)
{
IFields fields = table.Fields;
for (int i = 0; i < fields.FieldCount; i++)
{
IField field = fields.get_Field(i);
DataColumn dataColumn = new DataColumn(field.Name);
// 进行数据类型转换
switch (field.Type)
{
case esriFieldType.esriFieldTypeInteger:
dataColumn.DataType = typeof(int);
break;
case esriFieldType.esriFieldTypeSmallInteger:
dataColumn.DataType = typeof(short);
break;
case esriFieldType.esriFieldTypeDouble:
dataColumn.DataType = typeof(double);
break;
case esriFieldType.esriFieldTypeSingle:
dataColumn.DataType = typeof(float);
break;
case esriFieldType.esriFieldTypeString:
dataColumn.DataType = typeof(string);
break;
// 其他数据类型可根据需要添加转换逻辑
default:
dataColumn.DataType = typeof(object);
break;
}
dataTable.Columns.Add(dataColumn);
}
}
}
return dataTable;
}
步骤四:填充 DataTable 数据
从上一步得到的DataTable
只有字段信息,需要通过ICursor
从ITable
中逐一取出每一行数据(即IRow
),再创建DataTable
中相应的DataRow
,根据IRow
设置DataRow
信息,最后将所有的DataRow
添加
private DataTable FillDataTable(ITable table, DataTable dataTable, int maxRows = 2000)
{
IQueryFilter queryFilter = new QueryFilterClass();
ICursor cursor = table.Search(queryFilter, false);
IRow row;
int rowCount = 0;
while ((row = cursor.NextRow()) != null && rowCount < maxRows)
{
DataRow dataRow = dataTable.NewRow();
for (int i = 0; i < dataTable.Columns.Count; i++)
{
dataRow[i] = row.get_Value(i);
}
dataTable.Rows.Add(dataRow);
rowCount++;
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(cursor);
return dataTable;
}
到DataTable
中,完成数据的装载。为保证效率,可以限制一次装载的数据量。示例代码如下:
步骤五:绑定 DataTable 到 DataGridView
将填充好数据的DataTable
绑定到DataGridView
控件的数据源,从而实现属性数据表的显示。示例代码如下:
private void BindDataTableToDataGridView(DataTable dataTable, DataGridView dataGridView)
{
dataGridView.DataSource = dataTable;
}
步骤六:调用显示属性表
可以在特定的事件(如 TOCControl 中图层的右键菜单点击事件)中调用上述方法来显示属性表。以在 TOCControl 的OnMouseDown
事件中动态添加右键菜单项并显示属性表为例,需要自定义一个继承自BaseCommand
的类(如OpenAttributeTable
),在OnClick
函数中创建并打开属性表窗体。示例代码如下:
- 自定义 Command 类
2.在 TOCControl 的 OnMouseDown 事件中添加和移除菜单项using ESRI.ArcGIS.ADF.BaseClasses; using ESRI.ArcGIS.Controls; using System; using System.Windows.Forms; namespace AttributeTableDisplay { public class OpenAttributeTable : BaseCommand { private IMapControl3 mapControl; public OpenAttributeTable(IMapControl3 mapControl) { this.mapControl = mapControl; base.m_caption = "打开属性表"; } public override void OnClick() { ILayer selectedLayer = GetSelectedLayer(); if (selectedLayer != null) { DataTable dataTable = CreateEmptyDataTable(selectedLayer); IFeatureLayer featureLayer = selectedLayer as IFeatureLayer; ITable table = featureLayer.FeatureClass as ITable; dataTable = FillDataTable(table, dataTable); Form attributeForm = new Form(); DataGridView dataGridView = new DataGridView(); dataGridView.Dock = System.Windows.Forms.DockStyle.Fill; BindDataTableToDataGridView(dataTable, dataGridView); attributeForm.Controls.Add(dataGridView); attributeForm.Show(); } } public override void OnCreate(object hook) { mapControl = hook as IMapControl3; } private ILayer GetSelectedLayer() { IActiveView activeView = mapControl.ActiveView; IObjectSelectedEvent objectSelectedEvent = activeView as IObjectSelectedEvent; if (objectSelectedEvent != null) { IBasicMap basicMap = objectSelectedEvent.SelectedObject as IBasicMap; if (basicMap != null) { return basicMap as ILayer; } } return null; } } }
private void axTOCControl1_OnMouseDown(object sender, ESRI.ArcGIS.Controls.ITOCControlEvents_OnMouseDownEvent e)
{
if (e.button == 2) // 右键
{
ITOCControl2 tocControl = sender as ITOCControl2;
object hitTest = null;
object index = null;
tocControl.HitTest(e.x, e.y, ref hitTest, ref index);
ILayer layer = hitTest as ILayer;
if (layer != null)
{
IToolbarMenu toolbarMenu = new ToolbarMenuClass();
OpenAttributeTable openAttributeTableCommand = new OpenAttributeTable(axMapControl1.Object as IMapControl3);
toolbarMenu.AddItem(openAttributeTableCommand, -1, -1, false, esriCommandStyles.esriCommandStyleIconAndText);
toolbarMenu.ShowPopup(e.x, e.y, axTOCControl1.hWnd);
// 移除菜单项,防止重复添加
System.Runtime.InteropServices.Marshal.ReleaseComObject(toolbarMenu);
}
}
}