原文:《ArcGIS Engine+C#实例开发教程》第六讲 右键菜单添加与实现

摘要:在这一讲中,大家将实现TOCControl控件和主地图控件的右键菜单。在AE开发中,右键菜单有两种实现方式,一是使用VS2005自带的ContextMenuStrip控件,二是用AE封装的IToolbarMenu接口。相比较而言,后者更为简单实用,本文采用后者的实现方法。

教程目录:

第一讲 桌面GIS应用程序框架的建立

第二讲 菜单的添加及其实现

第三讲 MapControl与PageLayoutControl同步

第四讲 状态栏信息的添加与实现

第五讲 鹰眼的实现

第六讲 右键菜单添加与实现

教程Bug及优化方案1

第七讲 图层符号选择器的实现1

第七讲 图层符号选择器的实现2

第八讲 属性数据表的查询显示

------------------------------------------------------------------

在上一讲中,我们完成了鹰眼功能,在这一讲中,大家将实现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#实例开发教程》第六讲 右键菜单添加与实现的更多相关文章

  1. 《ArcGIS Engine+C#实例开发教程》第二讲 菜单的添加及其实现

    原文:<ArcGIS Engine+C#实例开发教程>第二讲 菜单的添加及其实现 摘要:在上一讲中,我们实现了应用程序基本框架,其中有个小错误,在此先跟大家说明下.在“属性”选项卡中,我们 ...

  2. 《ArcGIS Engine+C#实例开发教程》第一讲桌面GIS应用程序框架的建立

    原文:<ArcGIS Engine+C#实例开发教程>第一讲桌面GIS应用程序框架的建立 摘要:本讲主要是使用MapControl.PageLayoutControl.ToolbarCon ...

  3. 《ArcGIS Engine+C#实例开发教程》第七讲 图层符号选择器的实现2

    原文:<ArcGIS Engine+C#实例开发教程>第七讲 图层符号选择器的实现2 摘要:在第七讲 图层符号选择器的实现的第一阶段中,我们完成了符号选择器窗体的创建与调用.在第二阶段中, ...

  4. 《ArcGIS Engine+C#实例开发教程》第八讲 属性数据表的查询显示

    原文:<ArcGIS Engine+C#实例开发教程>第八讲 属性数据表的查询显示 第一讲 桌面GIS应用程序框架的建立 第二讲 菜单的添加及其实现 第三讲 MapControl与Page ...

  5. 《ArcGIS Engine+C#实例开发教程》第四讲 状态栏信息的添加与实现

    原文:<ArcGIS Engine+C#实例开发教程>第四讲 状态栏信息的添加与实现 摘要:在上一讲中,我们完成了 MapControl 和PageLayoutControl两种视图的同步 ...

  6. 《ArcGIS Engine+C#实例开发教程》第五讲 鹰眼的实现

    原文:<ArcGIS Engine+C#实例开发教程>第五讲 鹰眼的实现 摘要:所谓的鹰眼,就是一个缩略地图,上面有一个矩形框,矩形框区域就是当前显示的地图区域,拖动矩形框可以改变当前地图 ...

  7. 《ArcGIS Engine+C#实例开发教程》第三讲 MapControl与PageLayoutControl同步

    原文:<ArcGIS Engine+C#实例开发教程>第三讲 MapControl与PageLayoutControl同步 摘要:在ArcMap中,能够很方面地进行MapView和Layo ...

  8. 《ArcGIS Engine+C#实例开发教程》

    原文:<ArcGIS Engine+C#实例开发教程> 摘要:<ArcGIS Engine+C#实例开发教程>,面向 ArcGIS Engine(以下简称AE)开发初学者,本教 ...

  9. ArcGIS Runtime for Android开发教程V2.0(1)基本概念

    原文地址: ArcGIS Runtime for Android开发教程V2.0(1)基本概念 - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NET http://blog.csd ...

随机推荐

  1. jQuery Easy UI 使用

    一.引入必要文件 二.加载UI组件的方式 加载 UI 组件有两种方式: 1.使用 class 方式加载: 2.使用 JS 调用加载.//使用 class 加载,格式为: easyui-组件名 效果: ...

  2. wpf打印控件 实现分页打印控件功能

    因为 要实现打印 wpf  listbox控件  数据特别多 要打印在 几张纸上    找了几天 都没有找到相关的例子 现在 解决了 在这里和大家分享一下 public void print(Fram ...

  3. 使用for xml path 分组查询

     SELECT  OLevel, WorkOrgID, WorkOrgName, PlanNum, PlanFinishNum, PlanUnFinishNum, PlanCanceledNum, P ...

  4. [04] SQL语句优化之索引

    1.索引的概念 根据书的目录可以知道内容所在的页码,不用一页一页翻书,可直接通过页码找到内容.数据库的索引类似于书本的目录,索引指向内容存储位置,可直接定位到内容而不必扫描整张表,减少了磁盘的I/O次 ...

  5. 在Windows下用Mingw 4.5.2编译X264

    1.下载mingw-get-inst-20110530.rar(http://www.baidu.com/link?url=-ixXW6QiuEl8CA1dKudoWCxzcTvxrpQ0nXRBHU ...

  6. 实习笔记-3:ef实体操作错误篇

    学习笔记 1.json序列化ef实体是报错:“序列化类型为“System.Data.Entity.DynamicProxies.XXXX.... 对象时检测到循环引用.” 公司里用ef来生成实体.但是 ...

  7. 跟我一起学Vim补全神级插件--YouCompleteMe

    最近重拾Vim,编译部署来补全插件YCM,这个插件的补全效果和在写C代码的时候的自动提示错误信息等还是十分棒的,写点心得下来,也算给自己做个备忘. 快速安装: 首先参考我的.vimrc配置,用Vund ...

  8. mysql密码忘记后重置密码

    之前在centOS里安装了xampp,设置了mysql数据库root密码,今天需要增加个数据库,发现忘记之前设置的密码是什么了.经过一番摸爬滚打,终于搞明白了,注意以下的操作都是以linux的root ...

  9. top每个参数的意义

    上图来源于本人虚拟机,作为每个参数解释的参考 10:32:20:现在的时间 up 1 min : 服务器运行的时长 1 user:现在只有1个用户登录 load average: 0.74, 0.25 ...

  10. 鼠标事件(window.onload的自己的错误)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...