C#+AE开发TOCControl右键菜单打开属性表/图层目录右键功能
C# AE开发 TOCControl 右键打开图层属性表
致谢!
在ArcMap中,单击图层右键菜单中的“Open Attribute Table”命令,便可弹出属性数据表。本讲将完成类似的功能,效果如下:
图1
数据表显示,我们用了DataGridView控件。DataGridView 控件提供一种强大而灵活的以表格形式显示数据的方式。可以使用 DataGridView 控件来显示少量数据的只读视图,也可以对其进行缩放以显示特大数据集的可编辑视图。我们可以很方便地把一个DataTable作为数据源绑定到DataGridView控件中。
本讲的思路大体如下:首先根据图层属性中的字段创建一个空的DataTable,然后根据数据内容一行行填充DataTable数据,再将DataTable绑定到DataGridView控件,最后调用并显示属性表窗体。
创建属性表窗体
新建一个Windows窗体,命名为“AttributeTableFrm.cs”。
从工具箱拖一个DataGridView控件到窗体,并将其Dock属性设置为“Fill”。
添加如下引用:
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;
创建空DataTable
首先传入ILayer,再查询到ITable,从ITable中的Fileds中获得每个Field,再根据Filed设置DataTable的DataColumn,由此创建一个只含图层字段的空DataTable。实现函数如下:
/// <summary>
/// 根据图层字段创建一个只含字段的空DataTable
/// </summary>
/// <param name="pLayer"></param>
/// <param name="tableName"></param>
/// <returns></returns>
private static DataTable CreateDataTableByLayer(ILayer pLayer, string tableName)
{//创建一个DataTable表DataTable pDataTable = new DataTable(tableName);//取得ITable接口ITable pTable = pLayer as ITable;IField pField = null;DataColumn pDataColumn;//根据每个字段的属性建立DataColumn对象for (int i = 0; i < pTable.Fields.FieldCount; i++){pField = pTable.Fields.get_Field(i);//新建一个DataColumn并设置其属性pDataColumn = new DataColumn(pField.Name);if (pField.Name == pTable.OIDFieldName){pDataColumn.Unique = true;//字段值是否唯一}//字段值是否允许为空pDataColumn.AllowDBNull = pField.IsNullable;//字段别名pDataColumn.Caption = pField.AliasName;//字段数据类型pDataColumn.DataType = System.Type.GetType(ParseFieldType(pField.Type));//字段默认值pDataColumn.DefaultValue = pField.DefaultValue;//当字段为String类型是设置字段长度if (pField.VarType == 8){pDataColumn.MaxLength = pField.Length;}//字段添加到表中pDataTable.Columns.Add(pDataColumn);pField = null;pDataColumn = null;}return pDataTable;
}
因为GeoDatabase的数据类型与.NET的数据类型不同,故要进行转换。转换函数如下:
/// <summary>
/// 将GeoDatabase字段类型转换成.Net相应的数据类型
/// </summary>
/// <param name="fieldType">字段类型</param>
/// <returns></returns>
public static string ParseFieldType(esriFieldType fieldType)
{switch (fieldType){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";}
}
装载DataTable数据
从上一步得到的DataTable还没有数据,只有字段信息。因此,我们要通过ICursor从ITable中逐一取出每一行数据,即IRow。再创建DataTable中相应的DataRow,根据IRow设置DataRow信息,再将所有的DataRow添加到DataTable中,就完成了DataTable数据的装载。
为保证效率,一次最多只装载2000条数据到DataGridView。函数代码如下:
/// <summary>
/// 填充DataTable中的数据
/// </summary>
/// <param name="pLayer"></param>
/// <param name="tableName"></param>
/// <returns></returns>
public static DataTable CreateDataTable(ILayer pLayer, string tableName)
{//创建空DataTableDataTable pDataTable = CreateDataTableByLayer(pLayer, tableName);//取得图层类型string shapeType = getShapeType(pLayer);//创建DataTable的行对象DataRow pDataRow = null;//从ILayer查询到ITableITable pTable = pLayer as ITable;ICursor pCursor = pTable.Search(null, false);//取得ITable中的行信息IRow pRow = pCursor.NextRow();int n = 0;while (pRow != null){//新建DataTable的行对象pDataRow = pDataTable.NewRow();for (int i = 0; i < pRow.Fields.FieldCount; i++){//如果字段类型为esriFieldTypeGeometry,则根据图层类型设置字段值if (pRow.Fields.get_Field(i).Type == esriFieldType.esriFieldTypeGeometry){pDataRow[i] = shapeType;}//当图层类型为Anotation时,要素类中会有esriFieldTypeBlob类型的数据,//其存储的是标注内容,如此情况需将对应的字段值设置为Elementelse if (pRow.Fields.get_Field(i).Type == esriFieldType.esriFieldTypeBlob){pDataRow[i] = "Element";}else{pDataRow[i] = pRow.get_Value(i);}}//添加DataRow到DataTablepDataTable.Rows.Add(pDataRow);pDataRow = null;n++;//为保证效率,一次只装载最多条记录if (n == 2000){pRow = null;}else{pRow = pCursor.NextRow();}}return pDataTable;
}
上面的代码中涉及到一个获取图层类型的函数getShapeTape,此函数是通过ILayer判断图层类型的,代码如下:
/// <summary>
/// 获得图层的Shape类型
/// </summary>
/// <param name="pLayer">图层</param>
/// <returns></returns>
public static string getShapeType(ILayer pLayer)
{IFeatureLayer pFeatLyr = (IFeatureLayer)pLayer;switch (pFeatLyr.FeatureClass.ShapeType){case esriGeometryType.esriGeometryPoint:return "Point";case esriGeometryType.esriGeometryPolyline:return "Polyline";case esriGeometryType.esriGeometryPolygon:return "Polygon";default:return "";}
}
绑定DataTable到DataGridView
通过以上步骤,我们已经得到了一个含有图层属性数据的DataTable。现定义一个AttributeTableFrm类的成员变量:
public DataTable attributeTable;
通过以下函数,我们很容易将其绑定到DataGridView控件中:
/// <summary>
/// 绑定DataTable到DataGridView
/// </summary>
/// <param name="player"></param>
public void CreateAttributeTable(ILayer player)
{string tableName;tableName = getValidFeatureClassName(player .Name );attributeTable = CreateDataTable(player,tableName );this.dataGridView1 .DataSource = attributeTable ;this.Text = "属性表[" + tableName + "] " + "记录数:"+attributeTable.Rows.Count .ToString();
}因为DataTable的表名不允许含有“.”,因此我们用“_”替换。函数如下:
/// <summary>
/// 替换数据表名中的点
/// </summary>
/// <param name="FCname"></param>
/// <returns></returns>
public static string getValidFeatureClassName(string FCname)
{int dot = FCname.IndexOf(".");if (dot != -1){return FCname.Replace(".", "_");}return FCname;
}
调用属性表窗体
通过1-4步骤,我们封装了一个AttributeTableFrm类,此类能够由ILayer显示图层中的属性表数据。那怎么调用AttributeTableFrm呢?
前面已经提到,我们是在TOCControl选中图层的右键菜单中弹出属性表窗体的,因此我们需要添加一个菜单项到TOCControl中Layer的右键菜单。而在第六讲中,我们采用的是AE中的IToolbarMenu实现右键菜单的,故我们还需自定义一个Command,实现打开属性表的功能。
以ArcGIS的Base Command为模板新建项“OpenAttributeTable.cs”。
添加如下引用:
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
添加成员变量:
private ILayer m_pLayer;
修改构造函数为:
public OpenAttributeTable(ILayer pLayer)
{//// TODO: Define values for the public properties//base.m_category = ""; //localizable textbase.m_caption = "打开属性表"; //localizable textbase.m_message = "打开属性表"; //localizable text base.m_toolTip = "打开属性表"; //localizable text base.m_name = "打开属性表"; //unique id, non-localizable (e.g. "MyCategory_MyCommand")m_pLayer = pLayer;try{//// TODO: change bitmap name if necessary//string bitmapResourceName = GetType().Name + ".bmp";base.m_bitmap = new Bitmap(GetType(), bitmapResourceName);}catch (Exception ex){System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap");}
}
再在On_Click函数中添加如下代码,以创建并打开属性表窗体。
/// <summary>
/// Occurs when this command is clicked
/// </summary>
public override void OnClick()
{// TODO: Add OpenAttributeTable.OnClick implementationAttributeTableFrm attributeTable = new AttributeTableFrm();attributeTable.CreateAttributeTable(m_pLayer);attributeTable.ShowDialog();
}
至此,我们完成了OpenAttributeTable命令。显然,我们要在TOCControl的OnMouseDown事件中调用此命令。
因为,当前选中的图层参数,即ILayer是通过OpenAttributeTable的构造函数传入的,而选中的ILayer是动态变化的,所以我们无法在窗体初始化的Form1_Load事件中就添加OpenAttributeTable菜单项到右键菜单。但我们可以在OnMouseDown事件中动态添加OpenAttributeTable菜单项。
要注意的是,最后我们必须移除添加的OpenAttributeTable菜单项,不然每次按下右键都会添加此菜单项,将造成右键菜单中含有多个OpenAttributeTable菜单项。修改TOCControl的OnMouseDown事件的部分代码如下:
private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e)
{//……//弹出右键菜单if (item == esriTOCControlItem.esriTOCControlItemMap)m_menuMap.PopupMenu(e.x, e.y, m_tocControl.hWnd);if (item == esriTOCControlItem.esriTOCControlItemLayer){//动态添加OpenAttributeTable菜单项m_menuLayer.AddItem(new OpenAttributeTable(layer), -1, 2, true, esriCommandStyles.esriCommandStyleTextOnly);m_menuLayer.PopupMenu(e.x, e.y, m_tocControl.hWnd);//移除OpenAttributeTable菜单项,以防止重复添加m_menuLayer.Remove(2);}
}
//华丽丽的分割线///
TOCControl控件右键显示图层属性
(http://blog.sina.com.cn/s/blog_84f7fbbb01013ozt.html)
1 //实现控件的右键菜单项 2 private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e) 3 { 4 if (e.button != 2) return; 5 esriTOCControlItem pItem = esriTOCControlItem.esriTOCControlItemNone; 6 IBasicMap pMap = null; 7 ILayer pLayer = null; 8 object unk=null,data=null; 9 //内容表控件中的这个方法是根据鼠标的点击位置返回内容表中的项 10 axTOCControl1.HitTest(e.x,e.y,ref pItem,ref pMap,ref pLayer,ref unk,ref data); 11 //下面是判断鼠标选中的项是什么类型的项目(通过esriTOCControlItem的枚举值我们可以知道,针对不同的类型项可以添加不同的右键菜单(图层、Map对象、图例对象)) 12 if (pItem == esriTOCControlItem.esriTOCControlItemLayer) 13 { 14 /*第一种方法:使用contextMenuStrip控件 15 //下面的这个point是获得鼠标的点击位置。 16 System.Drawing.Point point = new System.Drawing.Point(); 17 //设置这个点的位置为鼠标的点击位置 18 point.X = e.x; 19 point.Y = e.y; 20 //显示右键菜单 21 contextMenuStrip1.Show(axTOCControl1, point); 22 show方法的两个参数:一个是右键菜单要关联的控件(或者是要显示右键菜单的控件)。另一个是:鼠标的点击位置 23 //该位置也是右键菜单四个角中,左上的这个位置*/ 24 //第二种方法:使用ToolbarMenu 25 IToolbarMenu pToolbarMenu = new ToolbarMenuClass();//创建工具条菜单类实例,相当与创建了一个菜单 26 //给菜单添加项目 27 pToolbarMenu.AddItem(new ControlsMapViewMenuClass () ,-1,-1,false,esriCommandStyles.esriCommandStyleIconAndText); 28 //设置菜单所关联的控件 29 pToolbarMenu.SetHook(axTOCControl1); 30 //根据鼠标的点击位置,弹出菜单 31 pToolbarMenu.PopupMenu(e.x,e.y,axTOCControl1.hWnd); 32 } 33 }
第二位博主的代码
//添加一个上下文菜单,添加一个新的Form窗体,在这个新的窗体上添加GridView控件,并在TOCControl控件的OnMouseDown事件下添加如下代码(pGlobalFeatureLayer是我定义的一个全局变量): private void axTOCControl1_OnMouseDown(object sender, ESRI.ArcGIS.Controls.ITOCControlEvents_OnMouseDownEvent e) {if (axMapControl1.LayerCount > 0){esriTOCControlItem pItem = new esriTOCControlItem();pGlobalFeatureLayer = 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 pGlobalFeatureLayer, ref pOther, ref pIndex);}if (e.button == 2){context.Show(axTOCControl1, e.x, e.y);} } //在上下文菜单的打开属性表的Click事件中添加如下代码: private void 打开属性表ToolStripMenuItem_Click(object sender, EventArgs e) {FormTable Ft = new FormTable(pGlobalFeatureLayer as IFeatureLayer);Ft.Show();}//在新的窗体中添加一个将属性表显示到GridView控件中的函数,如下: public void Itable2Dtable() {IFields pFields;pFields = pFeatureLayer.FeatureClass.Fields;dtGridView.ColumnCount = pFields.FieldCount;for (int i = 0; i < pFields.FieldCount;i++ ){string fldName = pFields.get_Field(i).Name;dtGridView.Columns[i].Name = fldName;dtGridView.Columns[i].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[i] = Convert.ToString(pFeature.Shape.GeometryType);}elsefldValue[i] = Convert.ToString(pFeature.get_Value(i));} dtGridView.Rows.Add(fldValue);pFeature = pFeatureCursor.NextFeature();} }
其他可参考 http://blog.csdn.net/zhushuaibing/article/details/40114309
2 private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e)
3 {
4 if (e.button != 2) return;
5 esriTOCControlItem pItem = esriTOCControlItem.esriTOCControlItemNone;
6 IBasicMap pMap = null;
7 ILayer pLayer = null;
8 object unk=null,data=null;
9 //内容表控件中的这个方法是根据鼠标的点击位置返回内容表中的项
10 axTOCControl1.HitTest(e.x,e.y,ref pItem,ref pMap,ref pLayer,ref unk,ref data);
11 //下面是判断鼠标选中的项是什么类型的项目(通过esriTOCControlItem的枚举值我们可以知道,针对不同的类型项可以添加不同的右键菜单(图层、Map对象、图例对象))
12 if (pItem == esriTOCControlItem.esriTOCControlItemLayer)
13 {
14 /*第一种方法:使用contextMenuStrip控件
15 //下面的这个point是获得鼠标的点击位置。
16 System.Drawing.Point point = new System.Drawing.Point();
17 //设置这个点的位置为鼠标的点击位置
18 point.X = e.x;
19 point.Y = e.y;
20 //显示右键菜单
21 contextMenuStrip1.Show(axTOCControl1, point);
22 show方法的两个参数:一个是右键菜单要关联的控件(或者是要显示右键菜单的控件)。另一个是:鼠标的点击位置
23 //该位置也是右键菜单四个角中,左上的这个位置*/
24
25
26
27 //第二种方法:使用ToolbarMenu
28 IToolbarMenu pToolbarMenu = new ToolbarMenuClass();//创建工具条菜单类实例,相当与创建了一个菜单
29 //给菜单添加项目
30 pToolbarMenu.AddItem(new ControlsMapViewMenuClass () ,-1,-1,false,esriCommandStyles.esriCommandStyleIconAndText);
31 //设置菜单所关联的控件
32 pToolbarMenu.SetHook(axTOCControl1);
33 //根据鼠标的点击位置,弹出菜单
34 pToolbarMenu.PopupMenu(e.x,e.y,axTOCControl1.hWnd);
35
转载于:https://www.cnblogs.com/marvelousone/p/7337566.html
C#+AE开发TOCControl右键菜单打开属性表/图层目录右键功能相关推荐
- 基于C#的AE二次开发之图层右键菜单打开属性表及图层相关操作
基于C#的AE二次开发之图层右键菜单打开属性表及图层相关操作 我的开发环境为ArcGIS Engine 10.2与Visual studio2010.主地图名称为axMapControl1,Toc目录 ...
- win7 计算机右键没有属性,系统之家windows7旗舰版计算机上右键菜单没有属性怎么办?...
使用win7旗舰版操作系统的时候,一些用户想查看系统属性,需要通过在计算机单击右键菜单中的"属性"选项才可以查看.但是有用户反映,计算机上点击右键之后没有"属性" ...
- 解决Windows资源管理器右键菜单打开EditPlus容易导致资源管理器无响应问题
解决Windows资源管理器右键菜单打开EditPlus容易导致资源管理器无响应问题 参考文章: (1)解决Windows资源管理器右键菜单打开EditPlus容易导致资源管理器无响应问题 (2)ht ...
- win7右键计算机管理参数错误,win7 64位旗舰版系统右键无法打开属性窗口的解决方法...
有用户反馈,本想给自己的Win7系统电脑更换一个背景后,但是右键打开win7属性窗口的时候却发现怎么也打不开了,不知是什么原因,该怎样解决?其实,右键打开属性窗口的功能有很多,它并不是局限于背景的设置 ...
- wpf datagrid设置右键菜单打开时选中项的背景色
原文:wpf datagrid设置右键菜单打开时选中项的背景色 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/huangli321456/artic ...
- 装了svn桌面右键没有_右键菜单没有svn选项怎么办|win7 svn没有右键菜单怎么解决|svn添加到右键菜单方法...
2016-05-31 11:43:55 最近,有位使用Windows10系统的朋友在下载了一个软件后,发现无法打开,显示为"XXX.RAR"格式的压缩文件,可是点击右键也没有发现& ...
- Mac OS X下删除或添加鼠标右键菜单项目及清除Mac OS右键菜单重复项
一.Mac OS X下删除或添加鼠标右键菜单项目 1. 打开 Finder,点击屏幕顶部菜单栏的 "前往",在下拉菜单里选择 "前往文件夹-" 2. 在弹出的输 ...
- ArcEngine C# GIS开发入门作业 (二)Ex03——基本应用程序生成,右击菜单实现:显示、移除和打开属性表功能
ArcEngine C# GIS开发入门作业 (二)Ex03--基本应用程序生成,右击菜单实现:显示.移除和打开属性表功能 这篇文章转自我舍友的文章,没有他的帮忙以我的基础和水平这个学期肯定学不懂AE ...
- linux在生信的作用,【生信笔记】右键菜单打开WSL功能方法简介
在人工智能以及生物信息学发展迅速的现在,充分掌握相关技术是非常重要的,而由于系统的差异,导致很多软件需要在Linux或者Mac OS上运行,长期以来,在Windows系统上解决这一难题的方式是安装虚拟 ...
最新文章
- 给input type=color设置默认值
- SQLServer之创建INSTEAD OF INSERT,UPDATE,DELETE触发器
- 斯蒂文斯理工学院计算机博士,美国斯蒂文斯理工大学——招收全奖土木工程博士生 - 导师招生 - 小木虫 - 学术 科研 互动社区...
- Spring Cloud Security:Oauth2使用入门
- 怎么确保一个集合不能被修改?
- scrcpy设置快捷键_scrcpy——Android投屏神器(使用教程)
- 转载 2012年游戏行业人才需求预测
- 利用.htaccess绑定域名到子目录
- JQuery中$.ajax()方法参数详解 转载
- 软件测试之软件配置项测试
- html设置字体为方正小标宋,如何安装方正小标宋字体
- VS中给qt按钮添加图标
- 世纪互联加入云计算专委会 推动应用进程
- html5做交互页面,分享9 个令你忍不住想狂点鼠标的趣味HTML 5 交互网站
- 在CAD里怎么测量面积?
- dll占的究竟是谁的空间?——浅谈Windows内存机制
- python3GUI--天气预报小工具(附源码)
- SPDY:一种更快速web的实验协议(转)
- 燕东微在科创板上市:市值263亿元,北京电控、亦庄国投等为股东
- matlab产生对称矩阵
热门文章
- 基于ubuntu环境搭建janus服务器
- 三面拼多多顺利斩获offer,来自初入职场的面试经验分享
- win10很多软件显示模糊_显示字体小到有些模糊?高分屏别忘了这些设置
- Django_Model详解
- 计算机性能的5个指标,计算机网络(一)—— 概述(5):计算机网络的性能指标...
- Milking Cows UASCO
- AutoCAD .NET 二次开发实例(5) 批量获取多段线所有顶点坐标
- c语言 杨辉三角形 直角形式和等腰三角形形式
- VSP存储配置SNMP
- SEED-XDS560v2 驱动