ArcEngine C# GIS开发入门作业 (二)Ex03——基本应用程序生成,右击菜单实现:显示、移除和打开属性表功能
这篇文章转自我舍友的文章,没有他的帮忙以我的基础和水平这个学期肯定学不懂AE开发,他的文章链接在这里 https://blog.csdn.net/m0_37768631/article/details/84196202
大家可以看看他的其他文章对我们这些入门水平的同学是很帮助的
前言:这里是我的笔记本
目录:
- 准备工作 - 工具方法等
- 代码
首先说明一下第一个作业,这是第二个的链接:https://pan.baidu.com/s/1NziPHoMEJx0vc8DCNrX-dA提取码:qpee看的时候希望能够静下心来看,不要着急,不然略过了信息可能后面代码看不懂,我的初衷是希望能够通过以下准备工作和理论讲解加深对我窗体工作的理解,急不得,有问题可留言啊,我尽量回复,毕竟代码内容有很多问题,还有错别字啥的HH,别介意。
- 代码为同学我的所有代码,但是完成度并非100%,一些小的改动和功能添加可以自行增补,而且带有个人习惯,所以重在属性功能;另外,同学我用的是10.2 + VS2012的环境,不同的版本应该有差异,虽然我这里测试无误,但是我不能保证其他人赋值粘贴过去后也能正常运行;
- 还有一点想强调一下,在开始写代码之前,准备工作不能落下,包括使用,嵌入操作,控件的命名,属性的设置,添加mapcontrol,lincensecontrol等等,可以省去一些不必要的麻烦。
第一个文章写的很烂,对于没有C#和窗体基础的同学可能较为吃力,但这个没办法啦,这毕竟是我的个人总结。大早爬起来终于把第二个写好了,现在写点总结。第一个作业的基础之后大致熟悉了窗体的基本操作,基本空间的使用,基本设置等等,如果没有,可以找一些视频或者自己看看书熟悉一下。
第二个作业实现的功能:
EX03 * :关系关系编写程序,地图显示坐标,工具条命令提示信息,并移除图层。
- 在状态栏显示地图中鼠标当前位置的坐标信息(地图控件的的的的的OnMouseMove)。
- 在状态栏显示工具条命令的提示信息(ToolbarControl的的的的的OnMouseMove,的的的的HitTest)。
在TOCControl的图层上按鼠标右键,移除该图层(TOCControl的onmousedown事件事件事件,的的的HitTest)
生成初始界面(带工具条);
- 鼠标移动显示坐标和工具状态信息;
- 右击菜单实现;
- 右击菜单中删除图层功能和AttributeTable打开功能。
标题 <p> </p> </li>
本次作业使用到的工具和方法,需了解,不若不易理解后续代码:
- ArcEngine的控件:地图控件,ToolbarControl,TOCControl(目录树),LicenseControl,中间两个不能够单独使用,必须与伙伴控件一起使用,所以在使用时我们需要将它们绑定到地图控件或页面...... .ToolbarControl绑定之后,我们就可以通过工具条对“伙伴控件”进行访问操作;同理,TOCControl可以用来显示“伙伴”的地图,图层,符号系统等内容的交互式视图→当在TOC中删除,隐藏图层时,地图控件中也会相应移除,不可见。
- 基本控件的常用属性,由于初始不熟悉,这里补充一下很多都是可以望文生义的属性,同时点击之后会有相应的功能描述,如下图所示:常用的码头,设置控件在窗体中的位置,文字文本显示等。
- 本次我用了stateStrip控件和的的ContextMenuStrip,toolStripContainer,的textBox中(可以直接在左侧工具栏搜索),也可以使用其他控件实现相同的功能,看个人习惯。至于这些功能基本的使用,可自行百度。这几个控件都比较搞,显示为了好还需要这几个设置位于顶层或者底层才行,忘记了,总之不要把地图控件下部分盖住。
- 引用的类库:
使用ESRI.ArcGIS.esriSystem;必须
使用ESRI.ArcGIS.Carto;必须
使用ESRI.ArcGIS.Controls;
使用ESRI.ArcGIS.SystemUI;
使用ESRI.ArcGIS.Geodatabase; //必须
非全部必须,具体使用可随时添加,这里地理数据库初始可能找不到,按下图所示方法查找即可:
- 函数说明https://blog.csdn.net/haizhongliangji/article/details/43955627
- public void HitTest(int X,int Y,ref esriTOCControlItem ItemType,ref IBasicMap BasicMap,ref ILayer
Layer,ref object unk,ref object Data);
各参数的含义如下:
X,Y:鼠标点击的坐标;
项目类型:esriTOCControlItem枚举常量
BasicMap:绑定地图控件的IBasicMap接口
层:被点击的图层
UNK:TOCControl的LegendGroup对象
数据:LegendClass在LegendGroup中的索引
.esriTOCControlItem枚举常量用于描述TocControl上的项目的类型,其定义如下:
esriTOCControlItemNone 0没有对象
esriTOCControlItemMap 1地图对象
esriTOCControlItemLayer 2图层对象
esriTOCControlItemHeading 3对象的标题
esriTOCControlItemLegendClass 4 LegendClass对象
这里我个人理解的为绑定TOC和地图控件后通过该函数来判断鼠标所处的位置,还有其他的功能但本次未用到。
C#几个经常用到的字符串截取,因为显示的字段类型还有一些单位,比如Meters会是esriMeters,Polyline则为esriGeometryPolyline,所以我用到了字符创截取功能:https://www.cnblogs。 com /lykbk/archive/2012/06/28/lyk1232132.html
如图1所示,取字符串的前我个字符
(1)string str1 = str.Substring(0,i);
(2)string str1 = str.Remove(i,str.Length -i);
2,去掉字符串的前我个字符
string str1 = str.Remove(0,i);
string str1 = str.SubString(i);
3,从右边开始取我个字符:
string str1 = str.SubString(str.Length -i);
string str1 = str.Remove(0,str.Length -i);
如图4所示,从右边开始去掉我个字符:
string str1 = str.Substring(0,str.Length -i);
string str1 = str.Remove(str.Length-i,i);
5,如果字符串中有“abc”则替换成“ABC”
str = str.Replace(“abc”,“ABC”);
6,C#截取字符串最后一个字符的问题!!!!!!!!!!!!!!!!!!!!
str1.Substring(str1.LastIndexOf(“”)+ 1);
7,C#截取字符串最后一个字符
k = k.Substring(k.Length-1,1);
就是还有基本窗体怎么生成的问题,就是自带工具条的那个,这里就不多此一举了,看这里http://zhihu.esrichina.com.cn/?/article/535与两种方法,我参考的的是它的第二种方式;这位前辈知乎上的教程不错,有6章,都可以看看但是有些代码拿过来还是有错HH,需要自己调试
生成之后添加工具如果不能使用(灰色的)需要注意,TolllBarControl绑定地图控件添加工具应该选择mapnevigation里的工具才会生效,有的是针对layerout ......这个同学我也还没去了解
http://zhihu.esrichina.com.cn/article/537这的英文右击菜单生成的方法,也是上面前辈的
还有选择控件时如果覆盖点不到,可以右击选择,就像图层一样也可以直接点下方的控件名称。
准备工作时很重要的,下面基本开始罗列代码了,再次声明,仅供参考!!!代码是使用CSDN编辑器C#选项,应该可复制。
代码
这是笔者的界面,下面是各个部分的代码,因为部分改了控件的名称属性,可能不一致,比如MapX的是lablestrip改名的,所以你在写代码的时候要改我的代码来适应你的窗体而不是通过我的代码来改动你的窗体和控件。
1,鼠标移动在地图上时,显示相关信息
private void axMapControl1_OnMouseMove(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseMoveEvent e)
{
string path = axMapControl1.DocumentFilename;
mapx.Text = "X:" + e.mapX.ToString("0.00");
mapy.Text = "Y:" + e.mapY.ToString("0.00");
//或者toolStripStatusLabel1.Text = Math.Round(e.mapX, 2).ToString();
mapunits.Text = this.axMapControl1.MapUnits.ToString().Remove(0,4);
//string str1 = str.Remove(0, i);
//string str1 = str.SubString(i);
textBox1.Text = "比例尺 1:" + ((long)this.axMapControl1.MapScale).ToString();
}
2,鼠标移动至工具条工具时,显示工具信息(索引初始索引为-1)
private void axToolbarControl1_OnMouseMove(object sender, ESRI.ArcGIS.Controls.IToolbarControlEvents_OnMouseMoveEvent e)
{
//取得鼠标所在工具的索引号
int index = axToolbarControl1.HitTest(e.x, e.y, false);
if (index != -1)
{
toolinfo.Text = axToolbarControl1.GetItem(index).Command.Message;
}
//toolinfo为我自己改的控件名,原来是statelable1,就是那个statestrip的子菜单
else
{
toolinfo.Text = "就绪";
}
}
3,右击菜单的实现,全局变量的设置就是因为前面讲到的几控件之间的关联关系
//右击菜单的实现
public ILayer pLayer;
private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e)
{
esriTOCControlItem pItem = new esriTOCControlItem();
pLayer = new FeatureLayerClass();
IBasicMap pBasicMap = new MapClass();
object pUnk = new object();
object pData = new object();
//实例化HITtest中的后五个参数
axTOCControl1.HitTest(e.x, e.y, ref pItem, ref pBasicMap, ref pLayer, ref pUnk, ref pData); //调用函数
if (e.button == 2 && pItem == esriTOCControlItem.esriTOCControlItemLayer)
//e.button=2代表鼠标右击,=1则是单击左键,pItem=...表示图层
{
contextMenuStrip1.Show(axTOCControl1, new Point(e.x, e.y));
}//如果点击的是图层,则弹出右击菜单
}
4,图层移除功能实现
private void removeLayerToolStripMenuItem_Click(object sender, EventArgs e)
{
if (axMapControl1.LayerCount > 0)
{
if (pLayer != null)
{
axMapControl1.Map.DeleteLayer(pLayer);
}
}
}
5,属性表功能实现,需要在这个项目里新建一个窗体,感觉比较复杂,直接摆出供参考
//属性表窗体连接并显示
private void openAtriiToolStripMenuItem_Click(object sender, EventArgs e)
{
AttributeTable pAttributeTable = new AttributeTable(pLayer as IFeatureLayer);
pAttributeTable.Show();
}
5.1,的的的dataGridView控件需要用于显示属性表,同时还需要设置属性时全局显示,没记错应该是AutoSizeColumnsMode,行两个,下面是代码,详情略
public partial class AttributeTable : Form
{
private IFeatureLayer pFeatureLayer = null;
public AttributeTable(IFeatureLayer _FeatureLayer)
{
InitializeComponent();
pFeatureLayer = _FeatureLayer;
}
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[i].Name = fldName;
dataGridView1.Columns[i].ValueType = 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] = pFeature.Shape.GeometryType.ToString().Remove(0,12);
}
else
fldValue[i] = pFeature.get_Value(i).ToString();
}
dataGridView1.Rows.Add(fldValue);//写入行值
pFeature = pFeatureCursor.NextFeature();
}
}
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";
}
}
}
代码就到这里结束了,但是可能还是会遇到很多问题,我也深有体会HH感谢你看完了,有需要的留言,博客可以修改这点是真的好用,当笔记本不错,下面是我的效果图(这个比例尺是可以直接添加的工具,我一开始没找到,就懒得改了,添加了比例尺工具就可以把我这里的关代码去除了):