zoukankan      html  css  js  c++  java
  • C#+AE开发TOCControl右键菜单打开属性表/图层目录右键功能

    文章转载自网易云博客,最初原创博客链接已失效,不再给出。仅给出转载链接:

    C# AE开发 TOCControl 右键打开图层属性表  

    致谢!

    ////////////////////////////////////////华丽丽的分割线/////////////////////////////////////////////////////

    在ArcMap中,单击图层右键菜单中的“Open Attribute Table”命令,便可弹出属性数据表。本讲将完成类似的功能。

    数据表显示,我们用了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)
    {
    	//创建空DataTable
    	DataTable pDataTable = CreateDataTableByLayer(pLayer, tableName);
    	//取得图层类型
    	string shapeType = getShapeType(pLayer);
    	//创建DataTable的行对象
    	DataRow pDataRow = null;
    	//从ILayer查询到ITable
    	ITable 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类型的数据,
    	        //其存储的是标注内容,如此情况需将对应的字段值设置为Element
    	        else if (pRow.Fields.get_Field(i).Type == esriFieldType.esriFieldTypeBlob)
    	        {
    	            pDataRow[i] = "Element";
    	        }
    	        else
    	        {
    	            pDataRow[i] = pRow.get_Value(i);
    	        }
    	    }
    	    //添加DataRow到DataTable
    	    pDataTable.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”。

    注意:新建Base Command模板时,会弹出一个对话框让我们选择模板适用对象,这时我们要选择MapControl、PageLayoutControl,即选择第二项或者倒数第二项。

    添加如下引用:

    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 text
    	base.m_caption = "打开属性表";  //localizable text
    	base.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 implementation
    	AttributeTableFrm 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);
    	}
    }

    //////////////////////////////////////////华丽丽的分割线///////////////////////////////////////////////////////

     
    根据作者的源码,我做了小小的修改,将所有函数直接添加进主程序窗口代码,函数前面的 public static 也改成 private
    一下是我的代码:
    /////////////////////////////////////////////////华丽丽的分割线/////////////////////////////////////////////////////////////////////////////
    #region 右键打开属性表
     
     
    ///菜单点击事件函数,其中SelectedLayer_TOC是TOCControl窗口当前选中的图层
            private void OpenAttribute_toolStripMenuItem1_Click(object sender, EventArgs e)
            {
                CreateAttributeTable(SelectedLayer_TOC);
                dataGridView1.Width = 300;
            }
     
            public DataTable attributeTable;
            /// <summary>
            /// 首先传入ILayer,再查询到ITable,从ITable中的Fileds中获得每个Field,再根据Filed设置DataTable的DataColumn,由此创建一个只含图层字段的空DataTable。
            /// </summary>
            /// <param name="pLayer"></param>
            /// <param name="tableName"></param>
            /// <returns></returns>
            private 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>
            private 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";
                }
            }
     
            /// <summary>
            /// 填充DataTable中的数据
            /// </summary>
            /// <param name="pLayer"></param>
            /// <param name="tableName"></param>
            /// <returns></returns>
            private DataTable CreateDataTable(ILayer pLayer, string tableName)
            {
                //创建空DataTable
                DataTable pDataTable = CreateDataTableByLayer(pLayer, tableName);
                //取得图层类型
                string shapeType = getShapeType(pLayer);
                //创建DataTable的行对象
                DataRow pDataRow = null;
                //从ILayer查询到ITable
                ITable 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类型的数据,
                        //其存储的是标注内容,如此情况需将对应的字段值设置为Element
                        else if (pRow.Fields.get_Field(i).Type == esriFieldType.esriFieldTypeBlob)
                        {
                            pDataRow[i] = "Element";
                        }
                        else
                        {
                            pDataRow[i] = pRow.get_Value(i);
                        }
                    }
                    //添加DataRow到DataTable
                    pDataTable.Rows.Add(pDataRow);
                    pDataRow = null;
                    n++;
                    //为保证效率,一次只装载最多条记录
                    if (n == 2000)
                    {
                        pRow = null;
                    }
                    else
                    {
                        pRow = pCursor.NextRow();
                    }
                }
                return pDataTable;
            }
     
            /// <summary>
            /// 获得图层的Shape类型
            /// </summary>
            /// <param name="pLayer">图层</param>
            /// <returns></returns>
            private 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 "";
                }
            }
     
            /// <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>
            private string getValidFeatureClassName(string FCname)
            {
                int dot = FCname.IndexOf(".");
                if (dot != -1)
                {
                    return FCname.Replace(".", "_");
                }
                return FCname;
            }
     
     
            #endregion
    /////////////////////////////////////////////////  分割线 【本博客补充】 ////////////////////////////////////////////////////////////
    作一点补充,两种方式打开右键菜单。也可以不创建OpenAttribute.cs类。
    或者

    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);
                }
                else
                    fldValue[i] = Convert.ToString(pFeature.get_Value(i));
            }               
            dtGridView.Rows.Add(fldValue);
            pFeature = pFeatureCursor.NextFeature();
        }
    }

     其他可参考 http://blog.csdn.net/zhushuaibing/article/details/40114309

    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
    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
     

  • 相关阅读:
    go语言学习之从例子开始
    分享一个不错的Unittest测试报告
    selenium各种定位方法(转)
    HTMLTESTRunner自动化测试报告增加截图功能
    selenium之chrome驱动版本
    Python基础(六) python生成xml测试报告
    vue+elementUI 表头按钮
    vue+elementUI滚动条
    vue表格表头添加按钮
    elementUI升级版本后Dialog弹空不显示问题
  • 原文地址:https://www.cnblogs.com/marvelousone/p/7337566.html
Copyright © 2011-2022 走看看