原文:《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. 提取数据表保存为XML文件

    //连接数据库 SqlConnection con = new SqlConnection("server=****;database=****;uid=sa;pwd=********&qu ...

  2. <转载>国外程序员推荐的免费编程书籍资源

    一.George Stocker 提供了一大串,分类如下: How to Design Programs: An Introduction to Computing and Programming 2 ...

  3. oracle随笔(转)

    ---------数学函数 1.绝对值S:select abs(-1) valueO:select abs(-1) value from dual 2.取整(大)S:select ceiling(-1 ...

  4. Python的对象操作(一)

    python支持对象和函数   1. python是解释型语言,逐行运行 2. 对象调用 例子:删除文件的一个例子 2.1 先定义一个类 class MyApp: 2.2 import 引用要用到的模 ...

  5. [DP] LGTB 玩THD (复杂状态DP)

    LGTB 玩THD LGTB 最近在玩一个类似DOTA 的游戏名叫THD有一天他在守一座塔,对面的N 个小兵排成一列从近到远站在塔前面每个小兵有一定的血量hi,杀死后有一定的金钱gi每一秒,他都可以攻 ...

  6. virtual析构函数的作用

    C++ Primter中讲“在 C++ 中,基类必须指出希望派生类重写哪些函数,定义为 virtual 的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数”. 析构函数是为了在 ...

  7. linux 下使用crontab 定时打包日志并删除已被打包的日志

    crontab是和用户相关的,每个用户有自己对应的crontab . cron是Linux下的定时执行工具,以下是重启/关闭等等的命令 #/sbin/service crond start //启动服 ...

  8. PHP 生成随机浮点数

    <?php /** * @desc 获取随机浮点数(支持最大最小值参数互换) * @date 2014-11-07 17:04:21 * * @param int|\最小浮点数 $min 最小浮 ...

  9. Pjax介绍及在asp.net MVC3中使用pjax的简单示例

    相信很多人对ajax并不陌生,对ajax的一些优点也了如指掌,如:局部刷新改善用户体验,减少开销,让服务器和浏览器之间的响应更快等. 但是它的缺点也是很显而易见的: AJAX大量的使用了javascr ...

  10. IQKeyboredManager使用

    这个库是一个单例,它一旦生效,全项目任何界面都有效.让它生效的代码可以写在任意位置,我写在AppDelegate里. 1 2 3 4 5 6 7 8 9 10 - (BOOL)application: ...