Arcengine窗体开发中,不同命令或者工具可能会触发同一控件的同一事件,这样会造成该事件中代码的混乱。以主窗体的AxMapcontrol控件为例,当开始画图时因为有很多种类型的Feature,所以在AxMapcontrol控件的OnMouseDown、OnMouseMove、OnMouseUp等事件中都需要作相应的处理。

  最简单的方法时利用if语句在各事件中做状态判断,来执行相应的语句。但是当你的程序达到一定规模的时候,你的这些事件中的代码将变的非常庞大,严重影响代码的可读性和可维护性,如图一所示。

图1 未重载事件代码组织结构

  下面介绍一种利用ARCGIS自带的ICommand和ITool模板重写控件事件。如下图所示

图2 重载事件代码组织结构

当需要编写某功能时,通过利用ICommand和ITools重写控件的事件,只需要将该功能需要执行的代码写入事件的重写中即可,程序一目了然,可读性和整体思路都会更将清晰。

下面是具体的操作步骤:

  1. 创建一个能运行的windows窗体程序,带有两个菜单命令、两个工具命令和一个mapcontrol控件,如图3所示。这部分比较简单,具体实现不再敖述。

图3.窗体设计

  2.添加ICommand类型扩展项

  ICommand主要用于重载菜单或者工具中点击之后立刻执行没有后续操作的功能,如创建新图层。

  具体操作如下:右键--à添加--à新建项,在左侧已安装的模板中选择ArcGIS--àExtending ArcObjects,在右侧选择”base command”,并填写文件名,这里我写的是OverwriteCommand1。在出现的”ArcGIS New Item Wizard Option”窗口中选择”MapControl or PageLayoutControl Command”,确定后解决方案资源管理器中将出现”OverwriteCommand1.cs”和”OverwriteCommand1.bmp”两个文件,表明已经添加成功。

在””OverwriteCommand1.cs”文件的OnClick()函数中添加具体的功能代码,并在“菜单1”的Click事件中添加如下代码:

pCmd = new OverwriteCommand1();

pCmd.OnCreate(axMapControl1.Object);

pCmd.OnClick();

同理,为”toolStripButton1”创建对应文件”OverwriteCommand2.cs”文件,并在Click方法中写入功能。在”toolStripButton1”的click事件中添加如下代码:

pCmd = new OverwriteCommand2();

pCmd.OnCreate(axMapControl1.Object);

pCmd.OnClick();

解释:pCmd为ICommand类型的全局对象,第一行利用OverwriteCommand1类的构造函数实例化pCmd对象。第二行将AxMapControl1的基类信息利用OverwriteCommand1的OnCreate方法传递给pCmd变量。第三行则是调用pCmd对象OnClick方法。

  3.添加ITool类型扩展项

ITools类型的扩展实现重写主要用于传递状态,方便有后续步骤的功能,如点击画图按钮后,需要在mapcontrol的onMouseDown、onMouseMove和onMouseUp等事件编写对应功能。

创建文件步骤如上,只是当出现在“添加新项”窗口中选择”Base Tool”而不是”Base Command”。确定后将成功创建”OverwriteTool1”和”OverwriteTool2”文件,这两个文件中除click事件,添加了OnMouseDown、OnMouseMove和OnMouseUp方法。将对应的功能写进这三个方法中。

在”菜单2”和”toolStripButton2”中分别写入如下文件:

pCmd = new OverwriteTool1();

pCmd.OnCreate(axMapControl1.Object);

axMapControl1.CurrentTool = pCmd as ITool;

pCmd = new OverwriteTool2();

pCmd.OnCreate(axMapControl1.Object);

axMapControl1.CurrentTool = pCmd as ITool;

解释:ITool类型和ICommand类型在调用时唯一的区别是第三行,ICommand类型是直接调用,而ITool则是将pCmd接口跳转成ITool类型后传递给AxMapControl1对象的CurrentTool属性。这事实上是状态的传递,传递成功后”菜单2”和”toolStripButton2”中重写的OnMouseDown、OnMouseMove和OnMouseUp将覆盖AxMapControl1对象原先的事件。

利用ICommand和ITool重写Arcengine中控件的事件的更多相关文章

  1. duilib中控件拖拽功能的实现方法(附源码)

    转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41144283 duilib库中原本没有显示的对控件增加拖拽的功能,而实际 ...

  2. C#中控件数组的讨论

    VB用得习惯后,到C#中来觉得很奇怪,如此好的控件数组怎么不见了.“众所周知,控件数组最主要的两个优点:可以循环附值:可以响应同一个事件.从而大大简化了代码.引自http://wenku.baidu. ...

  3. WPF 中获取DataGrid 模板列中控件的对像

    WPF 中获取DataGrid 模板列中控件的对像 #region 当前选定行的TextBox获得焦点 /// <summary> /// 当前选定行的TextBox获得焦点 /// &l ...

  4. Metro中控件WebView访问外部的网页显示一片空白

    Metro中控件WebView访问外部的网页显示一片空白 解决方案: ​下载安装了Initex.Software.Proxifier.v3.21.Standard.Edition.Incl.Keyma ...

  5. form表单中控件较多,加载完成后切换页面都很慢的解决方法

    form表单中控件较多,加载完成后点击都很慢,为什么?我一页面中form表单里面上百个控件(如input.select.radio.checkbox等),还有一些js脚本,加载速度还可以,都能全部显示 ...

  6. C#中控件的CheckState和Checked属性区别?

    Checked 和CheckState都是检查控件选中状态,都能判断是否选中控件. 只是Checked 通过布尔判断(true & false): CheckState 通过枚举判断. che ...

  7. MFC中控件的TAB顺序 ----转载

    在MFC中添加控件后,按Ctrl+d可以改变控件TAB顺序,怕自己忘了,一个神奇的东西,记下. 关于改变Tab顺序的方法有以下几种: 方法一:在动态创建控件的时候STYLE设置成为WS_CHILD|W ...

  8. WPF自定义控件(二)の重写原生控件样式模板

    话外篇: 要写一个圆形控件,用Clip,重写模板,去除样式引用圆形图片可以有这三种方式. 开发过程中,我们有时候用WPF原生的控件就能实现自己的需求,但是样式.风格并不能满足我们的需求,那么我们该怎么 ...

  9. WPF中控件的显示与隐藏

    1.WPF中控件的显示与隐藏的属性是 Visibility,它有3个枚举值 Visible, Hidden 和 Collapsed.其中Visible为可见,而 Hidden 和 Collapsed ...

随机推荐

  1. 不要怂,就是GAN (生成式对抗网络) (二)

    前面我们了解了 GAN 的原理,下面我们就来用 TensorFlow 搭建 GAN(严格说来是 DCGAN,如无特别说明,本系列文章所说的 GAN 均指 DCGAN),如前面所说,GAN 分为有约束条 ...

  2. XML基础<第一篇>

    一.XML简介 XML是一种标记语言,用于描述数据,它提供一种标准化的方式来来表示文本数据.XML文档以.xml为后缀.需要彻底注意的是XML是区分大小写的. 先从一个简单的XML例子来了解下xml基 ...

  3. Android使用自带JSONObject解析JSON数据

    import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android ...

  4. c++ 09

    一.数据结构 程序设计=数据结构+算法 1.逻辑结构 1)集合:元素之间没有联系. 2)线性结构:元素之间存在前后顺序. 3)树形结构:元素之间存在一对多的父子关系. 4)图状结构:元素之间存在多对多 ...

  5. 【LeetCode练习题】Recover Binary Search Tree

    Recover Binary Search Tree Two elements of a binary search tree (BST) are swapped by mistake. Recove ...

  6. 浅析libev的ev_signal过程

    ev_signal是libev提供的对信号处理的一个模块,基本上是对sigaction函数的一个封装,并将本身是异步的信号转化为同步.ev_signal的使用十分简单: #include <ev ...

  7. struts——拦截器

    什么是拦截器 拦截器(Interceptor)是Struts 2的一个强有力的工具,有许多功能都是构建于它之上,如国际化(前两篇博客介绍过).转换器,校验等. 拦截器是动态拦截Action调用的对象. ...

  8. java BingInteger生成2进制String循环移位时长度自动缩减

    最近在做文本处理,使用MD5 生成一段文字的MD5哈希长度为32位也即128个0-1序列. 由于需要对这个MD5值进行循环移位,显然普通的  int 是不行的,所以使用 BigInteger.但是在使 ...

  9. Oracle 学习笔记 19 -- 触发器和包浅析(PL/SQL)

    触发器是存放在数据库中的一种特殊类型的子程序.不能被用户直接调用,而是当特定事件或操作发生时由系统自己主动 调用执行.触发器不能接受參数.所以执行触发器就叫做触发或点火.Oracle事件指的是数据库的 ...

  10. Cocos2d-x 3.0rc0版本号项目的创建和部署

    <1>执行setup.py 依照提示.加入你须要加入的环境变量 <2>创建项目批处理文件Create-Cocos2d-x 3.0-Project.bat 内容例如以下: @ec ...