《ArcGIS Engine+C#实例开发教程》第六讲 右键菜单添加与实现
原文:《ArcGIS Engine+C#实例开发教程》第六讲 右键菜单添加与实现
教程目录:
第三讲 MapControl与PageLayoutControl同步
------------------------------------------------------------------
在上一讲中,我们完成了鹰眼功能,在这一讲中,大家将实现TOCControl控件和主地图控件的右键菜单。
在AE开发中,右键菜单有两种实现方式,一是使用VS2005自带的ContextMenuStrip控件,二是用AE封装的IToolbarMenu接口。相比较而言,后者更为简单实用,本文采用后者的实现方法。
1、创建右键菜单
在Form1类里面添加如下变量的定义:
//TOCControl控件变量
private ITOCControl2 m_tocControl = null; //TOCControl中Map菜单 private IToolbarMenu m_menuMap = null; //TOCControl中图层菜单 private IToolbarMenu m_menuLayer = null; 在Form1_Load函数进行初始化,即菜单的创建: m_menuMap = new ToolbarMenuClass(); m_menuLayer = new ToolbarMenuClass(); |
2、添加菜单项
第1步中创建的菜单可认为是菜单容器,里面什么都没有,具体的命令或工具作为菜单项添加到菜单容器才能工作。一般情况下,启动程序就要完成菜单项的添加,故此工作在Form1_Load函数完成。
当然,添加菜单项之前,必须实现相应命令或工具。这里的命令或工具可以AE内置的也可以是自定义的。AE内置了许多可以直接调用的常用命令和工具,如ControlsAddDataCommandClass,在ESRI.ArcGIS.Controls命名空间中,大家可以对象浏览器中查看。当然,这里也可以直接调用AE内置的菜单,如ControlsFeatureSelectionMenu。另外,本讲也实现三自定义命令,以做示范。它们分别为图层可视控制命令(用于控制图层显示与否)、移除图层和放大到整个图层命令。实现方法也很简单,就是右击3sdnMap项目,选择“添加|类”,选择C#普通的类模板,用以下代码覆盖系统自己生成的所有代码。
图层可视控制类LayerVisibility代码:
using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.SystemUI; namespace _sdnMap { /// <summary> /// 图层可视控制 /// </summary> public sealed class LayerVisibility : BaseCommand, ICommandSubType { private IHookHelper m_hookHelper = new HookHelperClass(); private long m_subType; public LayerVisibility() { } public override void OnClick() { for (int i=0; i <= m_hookHelper.FocusMap.LayerCount - 1; i++) { if (m_subType == 1) m_hookHelper.FocusMap.get_Layer(i).Visible = true; if (m_subType == 2) m_hookHelper.FocusMap.get_Layer(i).Visible = false; } m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography,null,null); } public override void OnCreate(object hook) { m_hookHelper.Hook = hook; } public int GetCount() { return 2; } public void SetSubType(int SubType) { m_subType = SubType; } public override string Caption { get { if (m_subType == 1) return "Turn All Layers On"; else return "Turn All Layers Off"; } } public override bool Enabled { get { bool enabled = false; int i; if (m_subType == 1) { for (i=0;i<=m_hookHelper.FocusMap.LayerCount - 1;i++) { if (m_hookHelper.ActiveView.FocusMap.get_Layer(i).Visible == false) { enabled = true; break; } } } else { for (i=0;i<=m_hookHelper.FocusMap.LayerCount - 1;i++) { if (m_hookHelper.ActiveView.FocusMap.get_Layer(i).Visible == true) { enabled = true; break; } } } return enabled; } } } } |
移除图层类RemoveLayer代码:
using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Controls; namespace _sdnMap { /// <summary> /// 删除图层 /// </summary> public sealed class RemoveLayer : BaseCommand { private IMapControl3 m_mapControl; public RemoveLayer() { base.m_caption = "Remove Layer"; } public override void OnClick() { ILayer layer = (ILayer)m_mapControl.CustomProperty; m_mapControl.Map.DeleteLayer(layer); } public override void OnCreate(object hook) { m_mapControl = (IMapControl3)hook; } } } |
放大至整个图层类ZoomToLayer:
using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Controls; namespace _sdnMap { /// <summary> /// 放大至整个图层 /// </summary> public sealed class ZoomToLayer : BaseCommand { private IMapControl3 m_mapControl; public ZoomToLayer() { base.m_caption = "Zoom To Layer"; } public override void OnClick() { ILayer layer = (ILayer)m_mapControl.CustomProperty; m_mapControl.Extent = layer.AreaOfInterest; } public override void OnCreate(object hook) { m_mapControl = (IMapControl3)hook; } } } |
以上三个工具或命令的实现代码比较简单,在此不过多的分析,请读者自行理解。
下面在Form1_Load函数中进行菜单项的添加,代码如下:
//添加自定义菜单项到TOCCOntrol的Map菜单中
//打开文档菜单 m_menuMap.AddItem(new OpenNewMapDocument(m_controlsSynchronizer), -1, 0, false, esriCommandStyles.esriCommandStyleIconAndText); //添加数据菜单 m_menuMap.AddItem(new ControlsAddDataCommandClass(), -1, 1, false, esriCommandStyles.esriCommandStyleIconAndText); //打开全部图层菜单 m_menuMap.AddItem(new LayerVisibility(), 1, 2, false, esriCommandStyles.esriCommandStyleTextOnly); //关闭全部图层菜单 m_menuMap.AddItem(new LayerVisibility(), 2, 3, false, esriCommandStyles.esriCommandStyleTextOnly); //以二级菜单的形式添加内置的“选择”菜单 m_menuMap.AddSubMenu("esriControls.ControlsFeatureSelectionMenu", 4, true); //以二级菜单的形式添加内置的“地图浏览”菜单 m_menuMap.AddSubMenu("esriControls.ControlsMapViewMenu",5, true); //添加自定义菜单项到TOCCOntrol的图层菜单中 m_menuLayer = new ToolbarMenuClass(); //添加“移除图层”菜单项 m_menuLayer.AddItem(new RemoveLayer(), -1, 0, false, esriCommandStyles.esriCommandStyleTextOnly); //添加“放大到整个图层”菜单项 m_menuLayer.AddItem(new ZoomToLayer(), -1, 1, true, esriCommandStyles.esriCommandStyleTextOnly); //设置菜单的Hook m_menuLayer.SetHook(m_mapControl); m_menuMap.SetHook(m_mapControl); |
3、
弹出右键菜单
顾名思义,右键菜单是在鼠标右键按下的时候弹出,所以我们要添加TOCControl1控件的OnMouseDown事件,实现代码如下:
private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e)
{ //如果不是右键按下直接返回 if (e.button != 2) return; esriTOCControlItem item = esriTOCControlItem.esriTOCControlItemNone; IBasicMap map = null; ILayer layer = null; object other = null; object index = null; //判断所选菜单的类型 m_tocControl.HitTest(e.x, e.y, ref item, ref map, ref layer, ref other, ref index); //确定选定的菜单类型,Map或是图层菜单 if (item == esriTOCControlItem.esriTOCControlItemMap) m_tocControl.SelectItem(map, null); else m_tocControl.SelectItem(layer, null); //设置CustomProperty为layer (用于自定义的Layer命令) m_mapControl.CustomProperty = layer; //弹出右键菜单 if (item == esriTOCControlItem.esriTOCControlItemMap) m_menuMap.PopupMenu(e.x, e.y, m_tocControl.hWnd); if (item == esriTOCControlItem.esriTOCControlItemLayer) m_menuLayer.PopupMenu(e.x, e.y, m_tocControl.hWnd); } |
同样的方法,我们也可以实现主地图控件的右键菜单,以方便地图浏览。添加MapControl1控件的OnMouseDown事件,实现代码如下:
/// <summary>
/// 主地图控件的右键响应函数 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e) { if (e.button == 2) { //弹出右键菜单 m_menuMap.PopupMenu(e.x,e.y,m_mapControl.hWnd); } } |
4、编译运行
按F5编译运行程序,你会发现,原来右键菜单实现起来是这么的简单啊!
《ArcGIS Engine+C#实例开发教程》第六讲 右键菜单添加与实现的更多相关文章
- 《ArcGIS Engine+C#实例开发教程》第二讲 菜单的添加及其实现
原文:<ArcGIS Engine+C#实例开发教程>第二讲 菜单的添加及其实现 摘要:在上一讲中,我们实现了应用程序基本框架,其中有个小错误,在此先跟大家说明下.在“属性”选项卡中,我们 ...
- 《ArcGIS Engine+C#实例开发教程》第一讲桌面GIS应用程序框架的建立
原文:<ArcGIS Engine+C#实例开发教程>第一讲桌面GIS应用程序框架的建立 摘要:本讲主要是使用MapControl.PageLayoutControl.ToolbarCon ...
- 《ArcGIS Engine+C#实例开发教程》第七讲 图层符号选择器的实现2
原文:<ArcGIS Engine+C#实例开发教程>第七讲 图层符号选择器的实现2 摘要:在第七讲 图层符号选择器的实现的第一阶段中,我们完成了符号选择器窗体的创建与调用.在第二阶段中, ...
- 《ArcGIS Engine+C#实例开发教程》第八讲 属性数据表的查询显示
原文:<ArcGIS Engine+C#实例开发教程>第八讲 属性数据表的查询显示 第一讲 桌面GIS应用程序框架的建立 第二讲 菜单的添加及其实现 第三讲 MapControl与Page ...
- 《ArcGIS Engine+C#实例开发教程》第四讲 状态栏信息的添加与实现
原文:<ArcGIS Engine+C#实例开发教程>第四讲 状态栏信息的添加与实现 摘要:在上一讲中,我们完成了 MapControl 和PageLayoutControl两种视图的同步 ...
- 《ArcGIS Engine+C#实例开发教程》第五讲 鹰眼的实现
原文:<ArcGIS Engine+C#实例开发教程>第五讲 鹰眼的实现 摘要:所谓的鹰眼,就是一个缩略地图,上面有一个矩形框,矩形框区域就是当前显示的地图区域,拖动矩形框可以改变当前地图 ...
- 《ArcGIS Engine+C#实例开发教程》第三讲 MapControl与PageLayoutControl同步
原文:<ArcGIS Engine+C#实例开发教程>第三讲 MapControl与PageLayoutControl同步 摘要:在ArcMap中,能够很方面地进行MapView和Layo ...
- 《ArcGIS Engine+C#实例开发教程》
原文:<ArcGIS Engine+C#实例开发教程> 摘要:<ArcGIS Engine+C#实例开发教程>,面向 ArcGIS Engine(以下简称AE)开发初学者,本教 ...
- ArcGIS Runtime for Android开发教程V2.0(1)基本概念
原文地址: ArcGIS Runtime for Android开发教程V2.0(1)基本概念 - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NET http://blog.csd ...
随机推荐
- Asp.Net Cookie的清除
背景 最近做到一个asp.net项目,项目中保存用户信息用到了cookie,因此,在注销身份的时候,就需要清除掉cookie. 探索过程 我先是试验了这种代码,在没有特殊声明前,代码都是写在Page_ ...
- 12天学好C语言——记录我的C语言学习之路(Day 1)
12天学好C语言--记录我的C语言学习之路 Day 1: 刚刚入门C语言,那么肯定要先把什么是C语言和大家讲清楚,那么大家看下面一段程序(program 1.1): /*//program 1.1 ...
- 【html】【7】基础布局初探
当了解了上面的文章有一定基础后,开始尝试初步基础布局,可能不美观,但是要开始有布局框架思想 基础代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML ...
- Sql 解释
SQL(Structured Query Language) 结构化查询语言,虽然是查询语言,也是一种编程语言,但是执行查询操作. 根据数据的操作对象,可以将SQL语句分为几类. DDL(Data D ...
- android API文档查询---context、toast、SharedPreferences
/*查阅api ---context1.abstract AssetManager getAssets() Returns an AssetManager instance for the a ...
- Java多线程间通信-解决安全问题、等待唤醒机制
/*1.增加一个知识点一个类怎么在所有的类中,让其它类来共同修改它的数据呢?可以用单例设计模式可以用静态可以在其它类中做一个构造函数,接受同一个对象,这样就可以实现对象 2.状态选择可以用数字0 1 ...
- C语言变参函数/Variadic fucntion
几个重要的 宏/类型 定义 Macros Defined in header <stdarg.h> va_start enables access to variadic function ...
- 使用qt制作简单的加法,乘法运算。
1.首先构架qt应用项目 2.然后打开使用 Qt desinger打开 Fomr File 里的UI文件进行编辑 3.由于此程序只需点击加号,减号这两个按钮,所以设置了两个信号槽 4.然后是连接信号槽 ...
- bzoj 1066: [SCOI2007] 蜥蜴
这道题还是挺好想的,但我一开始还是想错了…… 把每个石柱拆成两个点,一个入度,一个出度,两个点连一条容量为高度的边,这样就可以限制从此石柱上经过的蜥蜴的数量.关于蜥蜴是否单独成点,我是单独当成了一个点 ...
- NSInteger 与 NSUInteger 和 int与 NSInteger 区别(转)
转自:http://blog.csdn.net/duxinfeng2010/article/details/7606261 先说说NSInteger 与 NSUInteger,在看书上代码是遇见NSI ...