ArcObjects SDK开发 006 ICommand和ITool接口
1、ICommand接口
ICommand接口是插件协议之一,继承该接口的类都可以成为命令。即点击一下执行,不主动与宿主发生鼠标和键盘交互。该接口包含的重要成员如下表所示。
|
序号 |
名称 |
类型 |
描述 |
|
1 |
Bitmap |
Int |
命令上显示的图标 |
|
2 |
Caption |
String |
命令上显示的文字 |
|
3 |
Checked |
Bool |
命令是否处于选中状态 |
|
4 |
Enabled |
Bool |
命令当前是否可用 |
|
5 |
OnClick |
函数 |
点击命令时,触发执行的函数 |
|
6 |
OnCreate |
函数 |
创建该命令时,调用的函数 |
|
7 |
Tooltip |
String |
鼠标放到命令上要显示的文字 |
这些属性和函数的名字都比较容易理解,一看就知道其作用。如果我们自己继承ICommand实现一个弹出当前地图包含几个图层的命令,命名为LayerCountCommand。那么只要在OnClick函数中,获取OnCreate函数传进来的宿主对象,从宿主对象中获取当前加载的地图,进而获取其包含的几个图层,使用消息对话框弹出即可。
我们实现命令时候,只需要关注宿主对象就可以了,和其他Command不会发生直接关联。如果需要和其他Command关联,那么这些关联都通过宿主进行。例如我们刚才实现的LayerCountCommand在地图图层为0的时候,其处于不可用的状态,也就是 Enabled属性等于False。按照正常思维的话,我们会在OpenMapCommand里面,判断一下当前图层个数是否为0,从而设置设置LayerCountCommand实例的Enabled属性。那RemoveLayerCommand、AddLayerCommand、NewMapCommand等怎么办呢?难道每个命令里面都要判断LayerCountCommand是都可用?
当然不会是这样,我们会为宿主添加MapChanged和LayersChanged事件,无论用OpenMapCommand还是其他地方,在系统中打开一个新地图后,宿主对象就会触发MapChanged事件。而我们实现的LayerCountCommand会监测该事件,当该事件触发后,LayerCountCommand会判断当前地图有几个图层,从而设置自己是否是可用。
这样LayerCountCommand只关系宿主的信息,间接的和OpenMapCommand产生了关联。而LayerCountCommand自己可以决定自己是否可用,这就形成了高内聚,低耦合的设计。
2、ITool接口
ITool接口也是插件协议之一,实现该接口的类我们成为工具,这些工具是可以和地图显示控件进行鼠标、键盘交互的。该接口包含的重要成员如下表所示。
|
序号 |
名称 |
类型 |
描述 |
|
1 |
Cursor |
Int |
鼠标在地图显示控件上的样式 |
|
2 |
Deactivate |
函数 |
工具失活的时候触发的函数 |
|
3 |
OnMouseDown |
函数 |
鼠标按下执行的函数 |
|
4 |
OnMouseMove |
函数 |
鼠标移动执行的函数 |
|
5 |
OnMouseUp |
函数 |
鼠标弹起执行的函数 |
|
6 |
OnDblClick |
函数 |
鼠标双击地图显示控件执行的函数 |
|
7 |
OnKeyDown |
函数 |
键盘按键按下执行的函数 |
|
8 |
OnKeyUp |
函数 |
键盘按键弹起执行的函数 |
每个宿主对象都有CurrentTool属性,如果点击MapZoomInTool工具,那么该宿主的CurrentTool就是该工具了。当鼠标在宿主对象上按下的时候,会自动调用宿主对象CurrentTool属性值的OnMouseDown,也就是MapZoomInTool工具的OnMouseDown函数。当鼠标在宿主对象上移动的时候,会自动调用MapZoomInTool的OnMouseMove函数。其他动作一次类推,并且宿主对象读取CurrentTool的Cursor作为当前的鼠标样式。
要做一个放大工具,需要考虑拉框放大、点击放大等。但有了宿主程序,就可以把这些代码完整的封装到MapZoomInTool类中。而实现地图缩小功能MapZoomOutTool以及地图平移的MapPanTool,完全不需要知道其他工具的存在,也不关心其他Tool都做了什么。
在ArcMap中,地图放大、地图缩小、地图平移、地图全图地图即放大、地方即缩小、上一视图和下一视图这几个Tool和Command关系非常密切。如下图所示。

但通过这种插件式架构,他们不光代码之间无直接联系,而且还可以做到随意组合使用。例如我们开发的系统可以使用放大、缩小和平移三个工具,也可以加上全图,或者再加上其他工具,都可以正常运行。这种模式非常值得我们思考和借鉴。
3、ArcObjects SDK已经实现了哪些Command和Tool
AO中实现了二三百个命令和工具,我们常用的大概有几十个。可以在帮助中通过查看ICommand接口,查看到底有哪些实现。

也可以通过ArcMap查找,出现在ArcMap工具条上的按钮,大部分都能在此找到对应的类。
4、我们能借鉴到什么
ArcMap就是通过这种插件式架构把各种Command和Tool组合起来的,而这些Comamnd和Tool的背后是一个个功能点。不光使得ArcMap可以持续集成那么多功能,甚至可以开放接口,让开发人员直接在ArcMap上扩展。
那这种模式是不是可以借鉴到我们的软件开发中?答案是肯定的,下面我们就来设计自己的App-Command框架。
ArcObjects SDK开发 006 ICommand和ITool接口的更多相关文章
- sdk开发时,对外暴露的接口封装
思考,用同步还是异步? 实质就是屏蔽一些东西,让使用者直接传参数 拿结果 而不用关心具体实现 eg.登陆接口 1.定义接口LoginCallBack,两个函数 请求成功和失败 public inter ...
- 利用ICommand和ITool重写Arcengine中控件的事件
Arcengine窗体开发中,不同命令或者工具可能会触发同一控件的同一事件,这样会造成该事件中代码的混乱.以主窗体的AxMapcontrol控件为例,当开始画图时因为有很多种类型的Feature,所以 ...
- 微信公众账号 Senparc.Weixin.MP SDK 开发教程 索引
Senparc.Weixin.MP SDK从一开始就坚持开源的状态,这个过程中得到了许多朋友的认可和支持. 目前SDK已经达到比较稳定的版本,这个过程中我觉得有必要整理一些思路和经验,和大家一起分享. ...
- ThinkPHP3.2对接开发支付宝即时到帐接口
ThinkPHP3.2对接开发支付宝即时到帐接口 在做一些商城.自动发卡网站.会员积分充值.金币充值等等这类网站都时候,我们极大可能需要使用到第三方都支付接口.不管是财付通.支付宝.银联.贝宝.易宝这 ...
- 【转】微信公众账号 Senparc.Weixin.MP SDK 开发教程 索引
微信公众账号 Senparc.Weixin.MP SDK 开发教程 索引 Senparc.Weixin.MP SDK从一开始就坚持开源的状态,这个过程中得到了许多朋友的认可和支持. 目前SDK已经达到 ...
- 微信公众账号 Senparc.Weixin.MP SDK 开发教程
http://www.cnblogs.com/szw/archive/2013/05/14/weixin-course-index.html 微信公众账号 Senparc.Weixin.MP SDK ...
- Kinect for Windows SDK开发入门(15):进阶指引 下
Kinect for Windows SDK开发入门(十五):进阶指引 下 上一篇文章介绍了Kinect for Windows SDK进阶开发需要了解的一些内容,包括影像处理Coding4Fun K ...
- esp8266 SDK开发之环境搭建
最近在弄这个WiFi模块,发现网上SDK开发方面的资料很少,发现了一套视频教程,不过主讲人的讲课方式实在受不了.对基于SDK开发感兴趣的同学可以通过本帖在Ubuntu系统上通过Eclipes搭建开发环 ...
- 使用百度云 BOS 和 C# SDK 开发数据存储
Ø 简介 本文主要介绍如何使用百度云的 C# SDK 操作 BOS(Baidu Object Storage/百度对象存储),以及常见问题和解决办法.本文将以以下几点展开学习: 1. 基本介绍 ...
- 海康抓拍机SDK开发
前言 项目采购的海康威视的抓拍机,需要首先获取抓拍图片,之后基于抓拍图片进行图像处理.本文基于海康SDK开发文档,按照开发步骤,咨询海康技术人员,现将开发过程记录如下. 主要过程的c++代码: /** ...
随机推荐
- [Python]-json模块-处理字典数据的存取
import json 函数 json.dumps() json.dumps()函数是将字典转化为字符串 json.loads() json.loads()函数是将字符串转化为字典 注意: 从json ...
- DirectPV-----文章内容有待进一步实践完善
GitHub文档地址:https://github.com/minio/directpv DirectPV是用于直连存储的CSI驱动程序.从更简单的意义上讲,它是一个分布式持久卷管理器,而不是像SAN ...
- nginx+uwsgi+flask
说明:没用虚拟环境 安装nginx,并新建一个conf配置文件,启动nginx # xxx.conf server { listen 80; server_name localhost; locati ...
- 使用 systemd 定时器代替 cron 作业
转载自:https://mp.weixin.qq.com/s/HpDVp1sNYve8b7OdoHdGNw 创建一个定时器 首先,创建一个运行基础东西的简单的服务,例如 free 命令.举个例子,你可 ...
- 4_爬NMPA药监总局_动态加载_传ID
http://scxk.nmpa.gov.cn:81/xk/ import requests url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAc ...
- Opengl ES之FBO
FBO介绍 FBO帧缓冲对象,它的主要作用一般就是用作离屏渲染,例如做Camera相机图像采集进行后期处理时就可能会用到FBO.假如相机出图的是OES纹理,为了方便后期处理, 一般先将OES纹理通过F ...
- PAT (Basic Level) Practice 1007 素数对猜想 分数 20
让我们定义dn为:dn=pn+1−pn,其中pi是第i个素数.显然有d1=1,且对于n>1有dn是偶数."素数对猜想"认为"存在无穷多对相邻且差为2的 ...
- 安装 LAMP 环境(yum 版本) shell脚本
#!/bin/bash # 安装 LAMP 环境(yum 版本) # 本脚本适用于 RHEL7(RHEL6 中数据库为 mysql) yum makecache &>/dev/null ...
- JavaScript基本语法(数组与JSON)
5.数组 #①使用new关键字创建数组 // 1.创建数组对象 var arr01 = new Array(); // 2.压入数据 arr01.push("apple"); ar ...
- 服务器之Apollo单机部署(快速安装)
部署Apollo apollo单机部署(快速安装) Apollo官网:https://www.apolloconfig.com/#/zh/deployment/quick-start-docker 官 ...