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

简介: 原文:《ArcGIS Engine+C#实例开发教程》第六讲 右键菜单添加与实现摘要:在这一讲中,大家将实现TOCControl控件和主地图控件的右键菜单。在AE开发中,右键菜单有两种实现方式,一是使用VS2005自带的ContextMenuStrip控件,二是用AE封装的IToolbarMenu接口。
原文: 《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编译运行程序,你会发现,原来右键菜单实现起来是这么的简单啊!

目录
相关文章
|
7月前
|
自然语言处理 C# Windows
C#开源免费的Windows右键菜单管理工具
C#开源免费的Windows右键菜单管理工具
112 5
|
SQL 开发框架 数据可视化
ArcGIS Engine学习系列1 AE基础介绍
市面上AE教程大致到ArcGIS10.2,ESRI宣布从ArcGIS10.5开始便停止AE的更新,使用AO做开发,初学者可以在学习C#语言后,从AE入门,逐渐过度到AO。不同版本下AE数据类型数量Enums:枚举类型,用于实现一些定义的内容Structs:结构体Interfaces:接口Classes:类AE开发中,为了更好地管理COM对象,ESRI将这些COM对象放到不同的组件库中。
307 0
|
Shell API C#
(C#)Windows Shell 外壳编程系列3 - 上下文菜单(iContextMenu)(一)右键菜单
(本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢~)接上一节:(C#)Windows Shell 外壳编程系列2 - 解释,从“桌面”开始展开这里解释上一节中获取名称的方法 GetDisplayNameOf 定义: void GetDisplayNameOf(            IntPtr pidl,            SHGNO uFlags,            IntPtr lpName); 该方法是用来转换PIDL成为可显示的名称字符串。
1064 0
|
Web App开发 JavaScript 前端开发
ArcGIS API for JavaScript开发环境搭建及第一个实例demo
        ESRI公司截止到目前已经发布了最新的ArcGIS Server for JavaScript API v3.9,它提供了更为丰富而又强大的功能。
1157 0
|
定位技术 容器 索引
ArcGIS Engine Style文件操作
对于一个GISer来说,地图,符号这些都应该有着比别人更深刻的理解和认识,作为平台软件都会提供一套自己的符号库,符号库里面根据类别和种类进行区分,因为点,线,面的自然存在和固有属性是不肯能让你用面状符号去渲染点和线的,学GIS的人,一般都会有分类的意识。
1053 0
|
定位技术
ArcGIS Engine中的Symbols详解
本文由本人翻译ESRI官方帮助文档。尊重劳动成果,转载请注明来源。 Symbols     ArcObjects用了三种类型的Symbol(符号样式)来绘制图形特征:marker symbols(标记符号),line symbols(线符号),和fill symbols(填充符号)。
917 0
|
定位技术 C# C++
VC2010+ArcGIS Engine 10.1 开发(一)
                      使用MFC(VS2010)开发ArcGIS Engine 10.1 网上C#结合ArcGIS Engine的资料简直太多了,多的都无法形容,但是C++的却很少,前一段时间不断的有人问在VC中如何开发ArcGI...
1114 0
|
C# 定位技术
VC2010+ArcGIS Engine 10.1 开发(二)
采用ActiveX控件插入的方式 上面我们是通过代码直接将地图控件放到界面上,这种有一个不好的地方就是,如果我们要设置控件的一些样式和视觉效果,我们要自己写很多代码,在C#中我们就很容易,其实在VC中也可以采用这种方式,下来我介绍下: 插入控件 在Vi...
851 0