『公告』 预祝您龙年大吉,万事如意, 过节期间, 大家如需数据服务,请拨打400 或直接添加客服微信,再祝大家龙年,心想事成。
关注我们 新浪 腾讯

ArcGIS Engine 10 开发手册(3-8)命令和工具的宿主控件ToolBarControl控件

ArcGIS Engine 10 开发手册(3-8)命令和工具的宿主控件ToolBarControl控件
在 ToolBarControl 控件中,我们通过 ToolBarControl 控件的属性页面添加了一些如打开文档。

    在 ToolBarControl 控件中,我们通过 ToolBarControl 控件的属性页面添加了一些如打开文档,平移,放 大等功能,在 ArcGIS Engine 中我们将宿主在 ToolBarControl 控件中的内容分为三类“命令,工具,工具控 件“。

 

   命令,就是当用户单击时所产生的操作,比如说,我们要打开一个地图文档,我们只需要在ToolBarControl 控件上添加打开地图文档这个操作,然后用鼠标点击。

 

    工具,存在着交互这个操作。当我们在 ToolBarControl 控件上使用一个工具的时候,我们需要通过两 步操作:

 

     (1)单击这个工具;

 

     (2)使用这个工具更相应的控件做交互操作。

 

     如果我们点击了平移这个操作,那么这个时候我们还要用鼠标和地图进行平移等交互,那和谁交互呢,我们知道 ToolBarControl 有一个 buddy 属,这个就体现了在 buddy 属性上。ToolbarControl 会将伙伴控件的 CurrentTool 属性设置为我们用鼠标点击的工具,然后伙伴控件就等着和我们的工具交互。工具控件,这通 常是用户界面组件,如 ToolBarControl 控件上的列表框和组合框。其实在 ToolBarControl 控件中还可以宿主 工具条菜单(ToolbarMenu),工具条菜单表示单击命令项的一个垂直列表。用户必须选择工具条菜单上的 一个命令项,或单击工具条菜单之外的地方使其消失。工具条菜单只能驻留命令项(不允许驻留工具或者工 具控件)

 

     命令和工具

     在 ArcGIS Engine 中,命令是实现了 ICommand 接口,在 ArcGIS Engin 的开发帮助中,我们可以看到ICommand 接口以下成员:

 

 

 

     当用户单击这个命令时会导致 ICommand.OnClick 方法被调用,并执行某种操作。要将一个命令宿主到ToolBarControl 控件上,有以下三种方法:

 

     使用 UID

 

     使用 progID

 

    使用 ICommand

 

     UID pUID = new UIDClass ();

     pUID.Value = "esriControls.ControlsUndoCommand";

     axToolbarControl1.AddItem (pUID, - 1, 0, false, - 1, esriCommandStyles.esriCommandStyleIconOnly);

     axEditorToolbar.AddItem ("esriControls.ControlsUndoCommand", 0, - 1, true, 0, esriCommandStyles.esriCommandStyleIconOnly);

 

     ICommand pUndo = new ControlsUndoCommandClass ();

     axEditorToolbar.AddItem (pUndo, 0, - 1,false, 0,esriCommandStyles.esriCommandStyleIconOnly);

 

     ICommand 接口是可以被扩展的,也就是说这个接口对我们是开放的,只要我们将 ICommand 接口中 成员实现,因为这个格式是固定的,Esri 提供了相应的模板,如下图:

 

 

 

     我们知道宿主在 ToolBarControl 上的命令操作的对象是 ToolBarControl 的伙伴控件,但是,这个命令怎么和 这个伙伴控件联系起来了,注意到 ICommand 接口中有一个 ICommand.OnCreate 方法,这个方法有一个参 hook

 

    public void OnCreate (

    object hook

    }

      这个 hook 是一个 object 对象。也就是说这儿命令和那个控件协作,要看这个 hook 传入的是那种控件。 当命令 对象 宿主到 ToolBarControl 控件上后就 会立 即调用 ICommand.OnCreate 方法 ,同 时会 ToolBarControl 控件传递给 hook 这个参数,以便命令能和 ToolBarControl 控件的伙伴控件协作。一般要在 这个方法里面要测试这个 hook 是不是有效,也就是说这个命能不能和这个 hook 协作,要看这个命令支不 支持这样的操作,比如说我们要打开一个地图文档,我们知道打开地图文档这个命令是可以和 MapControl PageLayoutControl 控件协作的,如果我们传进去的是 TOCContro 控件,那么这个命令就会失效,这些话看 起来很费解,我们通过一个代码来好好体会这些话。我们自己定义一个打开地图文档的命令,利用 Esri 供的命令模板,如下:

 

 

 

     选择和命令对象协作的控件

 

 

using System;

using System.Drawing;

using System.Runtime.InteropServices;

using System.Windows.Forms;

using ESRI.ArcGIS.ADF.BaseClasses;

using ESRI.ArcGIS.ADF.CATIDs;

using ESRI.ArcGIS.Carto;

using ESRI.ArcGIS.Controls;

 

namespace EngineApplication {

  /// Summary description for OpenMxdCommand.

 

  [Guid ("c142fea5-2e8e-4f68-95e1-9cad4a6a290e")]

  [ClassInterface (ClassInterfaceType.None)]

  [ProgId ("CalculateContourTask.OpenMxdCommand")]

  public sealed class OpenMxdCommand : BaseCommand {

    #region COM Registration Function (s)

    [ComRegisterFunction ()]

    [ComVisible (false)]

    static void RegisterFunction (Type registerType) {

      // Required for ArcGIS Component Category Registrar support

      ArcGISCategoryRegistration (registerType);

      //

      // TODO: Add any COM registration code here

      //

    }

 

    [ComUnregisterFunction ()]

    [ComVisible (false)]

    static void UnregisterFunction (Type registerType) {

      // Required for ArcGIS Component Category Registrar support

      ArcGISCategoryUnregistration (registerType);

      //

      // TODO: Add any COM unregistration code here

      //

    }

 

    #region ArcGIS Component Category Registrar generated code

 

    /// Required method for ArcGIS Component Category registration -

    /// Do not modify the contents of this method with the code editor.

 

    private static void ArcGISCategoryRegistration (Type registerType) {

      string regKey = string.Format ("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);

      ControlsCommands.Register (regKey);

    }

 

    /// Required method for ArcGIS Component Category unregistration -

    /// Do not modify the contents of this method with the code editor.

 

    private static void ArcGISCategoryUnregistration (Type registerType) {

      string regKey = string.Format ("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);

      ControlsCommands.Unregister (regKey);

    }

 

    #endregion

    #endregion

 

    IMapControl2 pMapControl;

    public OpenMxdCommand () {

      //

      // TODO: Define values for the public properties

      //

      base.m_category = "打开地图文档"; //localizable text

      base.m_caption = "打开地图文档"; //localizable text

      base.m_message = "打开地图文档"; //localizable text

      base.m_toolTip = "打开地图文档"; //localizable text

 

      base.m_name = " 打开地图文档"; //unique id , non-localizable (e.g. "MyCategory_MyCommand")

      try

      {

        //

        // TODO: change bitmap name if necessary

        //

        string bitmapResourceName = GetType ().Name + ".bmp";

        base.m_bitmap = new Bitmap (GetType (), bitmapResourceName);

      } catch (Exception ex) {

        System.Diagnostics.Trace.WriteLine (ex.Message, "Invalid Bitmap");

      }

    }

 

    #region Overridden Class Methods

 

    /// Occurs when this command is created

 

    public override void OnCreate(object hook)

    {

      if (hook == null) return;

      //在这里对hook进行判断

      if (hook is IToolbarControl)

      {

        IToolbarControl pToolBar = hook as IToolbarControl;

        pMapControl = pToolBar.Buddy as IMapControl2;

      } else if (hook is IMapControl2)

      {

        pMapControl = hook as IMapControl2;

      }

      // TODO: Add other initialization code

    }

 

    /// Occurs when this command is clicked

 

    public override void OnClick ()

    {

 

      // TODO: Add OpenMxdCommand.OnClick implementation

      //launch a new OpenFile dialog

      OpenFileDialog pOpenFileDialog = new OpenFileDialog ();

      pOpenFileDialog.Filter = "Map Documents (*.mxd)|*.mxd";

      pOpenFileDialog.Multiselect = false;

      pOpenFileDialog.Title = "Open Map Document";

 

      if (pOpenFileDialog.ShowDialog () == DialogResult.OK)

      {

        string docName = pOpenFileDialog.FileName;

        IMapDocument pMapDoc = new MapDocumentClass ();

        if (pMapDoc.get_IsPresent (docName)&&!pMapDoc.get_IsPasswordProtected (docName))

        {

          pMapControl.LoadMxFile (pOpenFileDialog.FileName, null, null);

          // set the first map as the active view

          pMapControl.ActiveView.Refresh();

          pMapDoc.Close ();

        }

      }

    }

    #endregion

  }

}

通过下面两句将我们自定义的打开地图文档的命令宿主到 ToolBarControl

 

OpenMxdCommand pMxdCommand = new OpenMxdCommand ();

axToolbarControl1.AddItem (pMxdCommand, -1, 0, false, -1,  esriCommandStyles.esriCommandStyleIconOnly);

 

 

     运行结果

     使用该命令后,效果如下:

 

 

 

      我们可以对上述代码添加断点,发现当程序执行到 axToolbarControl1.AddItem(pMxdCommand, -1, 0, false, -1, esriCommandStyles.esriCommandStyleIconOnly);的时候,OnCreate 函数被执行,进而对 hook 参数判断,通过进一步跟踪,发现程序执行到

 

if (hook is IToolbarControl)

{

 

  IToolbarControl pToolBar= hook as IToolbarControl ;

  pMapControl = pToolBar.Buddy as IMapControl2;

 

}

说明程序将 ToolbarControl 控件传入进去。

 

工具是实现了 Itool ICommand 这两个接口,ITool 接口的成员几乎都是和交互相关的一些事件, ITool 的接口成员中我们就不难看出工具和命令的区别:

 

      京ICP备08100627号-22 京公网安备 11010802030428号