zoukankan      html  css  js  c++  java
  • AE属性表操作

    转自chanyinhelv原文AE属性表操作

    实现的操作包括:1、打开属性表;2、编辑属性表;3、增加属性列;4、数据排序;5、字段计算……

    嗯,实现的功能目前就这些吧,后续还会继续跟进,还望大家多多关注……下面就分功能说说我的实现方式吧……

    1、打开属性表

    属性表的打开是在TOC的右键菜单中打开的,首先新建一个类OpenAttribute,继承BaseCommand,OpenAttribute类的源码如下:

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using ESRI.ArcGIS.ADF.BaseClasses;  
    using ESRI.ArcGIS.Controls;  
      
    namespace MapDemo  
    {  
        public sealed class OpenAttribute : BaseCommand  
        {  
            IMapControl3 m_mapControl;  
            AxMapControl _MapControl;  
      
            public OpenAttribute(AxMapControl pMapControl)  
            {  
                base.m_caption = "查看属性表";  
                _MapControl = pMapControl;  
            }  
      
            public override void OnClick()  
            {  
                formTable formtable = new formTable(_MapControl, m_mapControl);  
                formtable.Show();  
      
            }  
      
            public override void OnCreate(object hook)  
            {  
                m_mapControl = (IMapControl3)hook;  
            }  
        }  
    }  

    解释一下,AxMapControl参数是为了后面属性表操作时刷新视图的。接着在toc右键事件中添加代码:

    m_menuLayer.AddItem(new OpenAttribute(mapMain), -1, 2, false, esriCommandStyles.esriCommandStyleIconAndText);

    如此这般,这般如此,我们期待的属性表就出现了,效果呢比较丑陋,莫怪莫怪……

    属性表打开之后呢,大家就看到了有关属性表操作的一些功能了,不过呢,属性表的大开的工作还尚未完成。接下来呢,添加如下引用:

     完了之后,定义一下变量:

      1. AxMapControl _MapControl;  
      2.         IMapControl3 m_mapControl;  
      3.         public DataTable dt2;          
      4.         ITableSort pTs;//处理排序  
      5.         bool up = true;  
      6.         int row_index = 0;  
      7.         int col_index = 0;  
      8.         public string strAddField = "";  
      9.         RowAndCol[] pRowAndCol = new RowAndCol[10000];  
      10.         int count = 0; 

    这个窗口的参数为:

    public formTable(AxMapControl pMapControl,IMapControl3 pMapCtrl)  
    {  
        InitializeComponent();  
        _MapControl = pMapControl;  
        m_mapControl = pMapCtrl;  
    }  

    这样,下面就可以显示属性了,在form_load事件中写如下代码:

    TableShow();

    此处,调用了TableShow方法,TableShow的代码如下:

    public void TableShow()  
    {  
        ILayer pLayer = (ILayer)m_mapControl.CustomProperty;  
        IFeatureLayer pFLayer = pLayer as IFeatureLayer;  
        IFeatureClass pFeatureClass = pFLayer.FeatureClass;  
      
        if (pFeatureClass == null) return;  
      
        DataTable dt = new DataTable();  
        DataColumn dc = null;  
      
        for (int i = 0; i < pFeatureClass.Fields.FieldCount; i++)  
        {  
      
            dc = new DataColumn(pFeatureClass.Fields.get_Field(i).Name);  
      
            dt.Columns.Add(dc);  
      
        }  
      
        IFeatureCursor pFeatureCuror = pFeatureClass.Search(null, false);  
        IFeature pFeature = pFeatureCuror.NextFeature();  
      
        DataRow dr = null;  
        while (pFeature != null)  
        {  
            dr = dt.NewRow();  
            for (int j = 0; j < pFeatureClass.Fields.FieldCount; j++)  
            {  
                if (pFeatureClass.FindField(pFeatureClass.ShapeFieldName) == j)  
                {  
      
                    dr[j] = pFeatureClass.ShapeType.ToString();  
                }  
                else  
                {  
                    dr[j] = pFeature.get_Value(j).ToString();  
      
                }  
            }  
      
            dt.Rows.Add(dr);  
            pFeature = pFeatureCuror.NextFeature();  
        }  
        gdvAttribute.DataSource = dt;  
        dt2 = dt;  
    }
    View Code

    这样呢,属性表的显示就完成了。

    2、新增字段

    先看看那个“新增字段”按钮的事件吧……

    ILayer pLayer = (ILayer)m_mapControl.CustomProperty; 

    IFeatureLayer pFLayer = pLayer as IFeatureLayer; 

    formAddField formaddfield = new formAddField(pFLayer, gdvAttribute); 

    formaddfield.Show(); 

    此处,调用了窗体formAddField ,传递的参数是IFeatureLayer pFLayer 和DataGridView gdvAttribute,那么,下面看看formAddField的设计以及实现

    界面呢也是比较简单,看看formAddField 的代码:

    using System;  
    using System.Collections.Generic;  
    using System.ComponentModel;  
    using System.Data;  
    using System.Drawing;  
    using System.Linq;  
    using System.Text;  
    using System.Windows.Forms;  
      
    using ESRI.ArcGIS.Carto;  
    using ESRI.ArcGIS.Geodatabase;  
    using ESRI.ArcGIS.Controls;  
      
    namespace MapDemo  
    {  
        public partial class formAddField : Form  
        {  
            private IFeatureLayer _FeatureLayer = null;  
            private DataGridView _dgv;  
            public formAddField(IFeatureLayer pFeatureLayer, DataGridView dgv)  
            {  
                InitializeComponent();  
                _FeatureLayer = pFeatureLayer;  
                _dgv = dgv;  
            }  
      
            private void formAddField_Load(object sender, EventArgs e)  
            {  
                this.cmbFieldType.Items.Add("长整型");  
                this.cmbFieldType.Items.Add("短整型");  
                this.cmbFieldType.Items.Add("浮点型");  
                this.cmbFieldType.Items.Add("双精度");  
                this.cmbFieldType.Items.Add("文本型");  
                this.cmbFieldType.Items.Add("日期型");  
                this.cmbFieldType.SelectedIndex = 0;  
            }  
      
            /// <summary>  
            /// 改变事件  
            /// </summary>  
            /// <param name="sender"></param>  
            /// <param name="e"></param>  
            private void cmbFieldType_SelectedIndexChanged(object sender, EventArgs e)  
            {  
                string strFieldType = cmbFieldType.Text;  
                switch (strFieldType)  
                {  
                    case "长整型":  
                        {  
                            panelPrecision.Visible = true;  
                            panelScale.Visible = false;  
                            break;  
                        }  
                    case "短整型":  
                        {  
                            panelPrecision.Visible = true;  
                            panelScale.Visible = false;  
                            break;  
                        }  
                    case "浮点型":  
                        {  
                            panelPrecision.Visible = true;  
                            panelScale.Visible = true;  
                            break;  
                        }  
                    case "双精度":  
                        {  
                            panelPrecision.Visible = true;  
                            panelScale.Visible = true;  
                            break;  
                        }  
                    case "文本型":  
                        {  
                            panelPrecision.Visible = true;  
                            panelScale.Visible = false;  
                            lblPrecision.Text = "长度";  
                            break;  
                        }  
                    default://日期型0  
                        {  
                            panelPrecision.Visible = false;  
                            panelScale.Visible = false;  
                            break;  
                        }  
                }   
            }  
      
            private void btnOK_Click(object sender, EventArgs e)  
            {  
                string strFieldName = txtFieldName.Text;  
                string strFieldType = cmbFieldType.Text;  
                try  
                {  
                    IFeatureLayer editAttributeLayer = _FeatureLayer;  
      
                    //Field collection  
                    IFieldsEdit pFieldsEdit;  
                    //获取FeatureLayer  
                    IFeatureLayer pFeatureLayer = editAttributeLayer;  
      
                    //从FeatureLayer获取工作空间  
                    IDataset pDataSet = pFeatureLayer.FeatureClass as IDataset;  
                    IWorkspace pWorkSpace = pDataSet.Workspace;  
                    //设置字段属性  
                    IField pNewField = new FieldClass();  
                    IFieldEdit pFieldEdit = pNewField as IFieldEdit;  
                    pFieldEdit.AliasName_2 = strFieldName;  
                    pFieldEdit.Name_2 = strFieldName;  
                    switch (strFieldType)  
                    {  
                        case "长整型":  
                        {  
                            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;  
                            pFieldEdit.Precision_2 = int.Parse(txtPrecision.Text);  
                            break;  
                        }  
                        case "Class1.cs短整型":  
                        {  
                            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeSmallInteger;  
                            pFieldEdit.Precision_2 = int.Parse(txtPrecision.Text);  
                            break;  
                        }  
                        case "浮点型":  
                        {  
                            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeSingle;  
                            pFieldEdit.Precision_2 = int.Parse(txtPrecision.Text);  
                            pFieldEdit.Scale_2 = int.Parse(txtScale.Text);  
                            break;  
                        }  
                        case "双精度":  
                        {  
                            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble;  
                            pFieldEdit.Precision_2 = int.Parse(txtPrecision.Text);  
                            pFieldEdit.Scale_2 = int.Parse(txtScale.Text);  
                            break;  
                        }  
                        case "文本型":  
                        {  
                            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;  
                            pFieldEdit.Length_2 = int.Parse(txtPrecision.Text);  
                            break;  
                        }  
                        default://日期型0  
                        {  
                            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeDate;  
                            break;  
                        }  
                    }                 
                    //添加字段  
                    try  
                    {  
                        int theField = pFeatureLayer.FeatureClass.Fields.FindField(strFieldName);  
                        if (theField == -1)  
                        {  
                            pFeatureLayer.FeatureClass.AddField(pFieldEdit);  
                            MessageBox.Show("字段添加成功!");  
                        }  
                        else  
                        {  
                            MessageBox.Show("字段已经存在!");  
                        }  
                    }  
                    catch (Exception ex)  
                    {  
                        MessageBox.Show("Field " + pFieldEdit.Name + " was not added due to an error (" + ex.Message + " )");  
                    }  
      
                }  
                catch (System.Exception ex)  
                {  
                    MessageBox.Show(ex.Message);  
                }              
                this.Close();  
                RefreshTable refresh = new RefreshTable();  
                refresh.Refresh(_dgv, _FeatureLayer);  
            }  
      
            private void btnCancle_Click(object sender, EventArgs e)  
            {  
                this.Close();  
            }          
        }  
    }  
    View Code

    首先,在窗体加载的时候将数据类型添加进去,之后在类型选择改变时触发其属性控制控件的显示或者改变,接下来就是最重要的添加字段了,大家注意到了,在this.Close()之后,还调用了RefreshTable 的Refresh方法,传递的参数是datagridview _dgv和Ifeaturelayer _FeatureLayer,Refresh方法主要是实现添加自断后显示的刷新,由于后面还有涉及到,所以,这个后面一并说。

    3、编辑属性并保存

    还是先看看那两个按钮的时间吧:

    private void toolEditor_Click(object sender, EventArgs e)  
    {  
        gdvAttribute.ReadOnly = false;  
        this.gdvAttribute.CurrentCell = this.gdvAttribute.Rows[this.gdvAttribute.Rows.Count - 2].Cells[0];  
    }  
      
     /// <summary>  
    /// 保存编辑  
    /// </summary>  
    /// <param name="sender"></param>  
    /// <param name="e"></param>  
    private void toolSave_Click(object sender, EventArgs e)  
    {  
        gdvAttribute.ReadOnly = true;  
        ILayer pLayer = (ILayer)m_mapControl.CustomProperty;  
        IFeatureLayer pFLayer = pLayer as IFeatureLayer;  
        IFeatureClass pFeatureClass = pFLayer.FeatureClass;  
        ITable pTable;  
        //pTable = pFeatureClass.CreateFeature().Table;//很重要的一种获取shp表格的一种方式           
        pTable = pFLayer as ITable;  
        //将改变的记录值传给shp中的表  
        int i = 0;  
        while (pRowAndCol[i].Column != 0 || pRowAndCol[i].Row != 0)  
        {  
            IRow pRow;  
            pRow = pTable.GetRow(pRowAndCol[i].Row);  
            pRow.set_Value(pRowAndCol[i].Column, pRowAndCol[i].Value);  
            pRow.Store();  
            i++;  
        }  
        count = 0;  
        for (int j = 0; j < i; j++)  
        {  
            pRowAndCol[j].Row = 0;  
            pRowAndCol[j].Column = 0;  
            pRowAndCol[j].Value = null;  
        }  
        MessageBox.Show("保存成功!", "提示", MessageBoxButtons.OK);  
    }
    View Code

    在保存属性表的时候,出现了pRowAndCol,对他的定义如下:

    public struct RowAndCol  
    {  
        //字段  
        private int row;  
        private int column;  
        private string _value;  
          
        //行属性  
        public int Row  
        {  
            get  
            {  
                return row;  
            }  
            set  
            {  
                row = value;  
            }  
        }  
        //列属性  
        public int Column  
        {  
            get  
            {  
                return column;  
            }  
            set  
            {  
                column = value;  
            }  
        }  
        //值属性  
        public string Value  
        {  
            get  
            {  
                return _value;  
            }  
            set  
            {  
                _value = value;  
            }  
        }  
    }  
    View Code

    4、删除选择

    顾名思义,就是删除选择的行,这里的选择可以是多选,也可是单选,看看对应按钮的事件吧:

    private void toolDelSelect_Click(object sender, EventArgs e)  
    {  
        if (((MessageBox.Show("确定要删除吗", "警告", MessageBoxButtons.YesNo)) == DialogResult.Yes))  
        {  
            ILayer pLayer = (ILayer)m_mapControl.CustomProperty;  
            IFeatureLayer pFLayer = pLayer as IFeatureLayer;  
            ITable pTable = pFLayer as ITable;  
            IRow pRow = pTable.GetRow(row_index);  
            pRow.Delete();  
            TableShow();  
            MessageBox.Show("删除成功!", "提示", MessageBoxButtons.OK);  
            _MapControl.ActiveView.Refresh();  
        }  
    }  

    此处,看看下面这个事件:

    private void gdvAttribute_CellValueChanged(object sender, DataGridViewCellEventArgs e)  
    {  
        //记录值一旦改变触发此事件  
        //在dataGridView中获取改变记录的行数,列数和记录值  
        pRowAndCol[count].Row = gdvAttribute.CurrentCell.RowIndex;  
        pRowAndCol[count].Column = gdvAttribute.CurrentCell.ColumnIndex;  
        pRowAndCol[count].Value = gdvAttribute.Rows[gdvAttribute.CurrentCell.RowIndex].Cells[gdvAttribute.CurrentCell.ColumnIndex].Value.ToString();  
        count++;  
    }  


    5、导出Excel

    首先得添加程序对Microsoft.Office.Interop.Excel的引用,添加完成之后方可导出:

    private void toolExpXLS_Click(object sender, EventArgs e)  
    {  
        ILayer pLayer = (ILayer)m_mapControl.CustomProperty;  
        IFeatureLayer pFLayer = pLayer as IFeatureLayer;  
        IFeatureClass pFeatureClass = pFLayer.FeatureClass;  
        IFields pFields = pFeatureClass.Fields;  
        ExportExcel(gdvAttribute, pFields);  
    }  
      
    private void ExportExcel(DataGridView myDGV, IFields pFields)  
    {  
        string saveFileName = "";  
        SaveFileDialog saveDialog = new SaveFileDialog();  
        saveDialog.DefaultExt = "xls";  
        saveDialog.Filter = "Excel文件|*.xls";  
        saveDialog.ShowDialog();  
        saveFileName = saveDialog.FileName;  
        if (saveFileName.IndexOf(":") < 0) return; //被点了取消   
      
        Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();  
        if (xlApp == null)  
        {  
            MessageBox.Show("无法创建Excel对象,可能您的机子未安装Excel");  
            return;  
        }  
      
        Microsoft.Office.Interop.Excel.Workbooks workbooks = xlApp.Workbooks;  
        Microsoft.Office.Interop.Excel.Workbook workbook = workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);  
        Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets[1];//取得sheet1  
      
        //写入标题  
        for (int i = 0; i < myDGV.ColumnCount; i++)  
        {  
            worksheet.Columns.Cells[1, i + 1] = myDGV.Columns[i].HeaderText;  
        }  
        //写入数值  
        for (int r = 0; r < myDGV.Rows.Count; r++)  
        {  
            for (int i = 0; i < myDGV.ColumnCount; i++)  
            {  
                worksheet.Cells[r + 2, i + 1] = myDGV.Rows[r].Cells[i].Value;  
            }  
            System.Windows.Forms.Application.DoEvents();  
        }  
      
        worksheet.Columns.EntireColumn.AutoFit();//列宽自适应  
      
        if (saveFileName != "")  
        {  
            try  
            {  
                workbook.Saved = true;  
                workbook.SaveCopyAs(saveFileName);  
            }  
            catch (Exception ex)  
            {  
                MessageBox.Show("导出文件时出错,文件可能正被打开!
    " + ex.Message);  
            }  
            xlApp.Quit();  
            GC.Collect();//强行销毁   
            MessageBox.Show("资料保存成功", "提示", MessageBoxButtons.OK);  
        }  
    }
    View Code



  • 相关阅读:
    Github基于Web的编辑器
    科技爱好者周刊(第 172 期):我们会死于气候灾难吗?
    走进京东618大促“产星”之路
    科技爱好者周刊(第 171 期):云服务流量有多贵?
    科技爱好者周刊(第 170 期):软件订阅制的胜利
    科技爱好者周刊(第 169 期):五菱汽车的产品设计
    在Chrome中打开网页时出现以下问题 您的连接不是私密连接 攻击者可能会试图从 x.x.x.x 窃取您的信息(例如:密码、通讯内容或信用卡信息)
    mac 更新到big sur 后,parallels虚拟机的一些问题:由于您尚未获得访问其中一些文件的授权,所以您不能恢复“Windows 10
    React/Vue 项目在 GitHub Pages 上部署时资源的路径问题
    科技爱好者周刊(第 168 期):游戏《底特律:变人》
  • 原文地址:https://www.cnblogs.com/arxive/p/6262332.html
Copyright © 2011-2022 走看看