【轉貼】ArcEngine開發之Command控件使用篇

在ArcEngine類庫中有大量的Command控件用來與地圖控件進行操作和交互。比如有一系列的地圖瀏覽控件、地圖查詢控件、圖斑選取控件、編輯控件來與MapControl和PageLayoutControl進行交互。這些控件被包含在ESRI.ArcGIS.Controls.dll類庫中,位於ESRI.ArcGIS.Controls命名空間下。

這些內置的Command控件可以單獨實例化來使用,也可以被安置在一個AxToolbarControl工具欄控件中,繼而被存放在一個CommandPool池中以備調用。下面對這兩種方式分別加以說明:

第一種使用方式是實例化一個Command對象並顯式地運行它:
 

ICommand command = new ControlsOpenDocCommandClass();
command.OnCreate(m_mapControl.Object);
command.OnClick();


其中ControlsOpenDocCommandClass就是一個Command控件,通過調用它的OnCreate方法傳遞給它需要交互的MapControl,然後調用它的OnClick方法就可以運行。上面的例子會激活一個打開地圖文檔的對話框。

另一種方法是更加常用的方法。

由於每個Command對象都是一個COM組件,所以ESRI.ArcGIS.Controls下的各個類只是對底層的COM對象的一種封裝。由於是COM對象,所以每一個Command對象都有自己的CLSID和ProgID,並在安裝Engine Runtime的時候被註冊了,你可以在註冊表的HKEY_LOCAL_MACHINE/SOFTWARE/Classes/CLSID/找到這些Command的註冊信息,如果要查找所有Command的信息,請訪問Built-in commands。由於是COM組件,在實例化它的過程中,.net需要實例化一個Runtime Callable Wrapper(RCW)對象,來代理對COM組件的調用。


由於大部分對地圖控件的操作都直接或間接的來自於工具欄,比如點擊工具欄上面的放大、縮小、全圖按鈕。那麼實際上我們的絕大部分Command對象都可以被寄放到這個工具欄之中。方法非常簡單:

axToolbarControl1.AddItem("esriControls.ControlsMapZoomInTool");


此處使用的esriControls.ControlsMapZoomInTool就是ControlsMapZoomInToolClass類所指向的COM組件的ProgID,需要所有這些Command的信息時,你應該到Built-in commands這個頁面下查找,或在你的Engine幫助文檔中ms-help://ESRI.EDNv9.2/NET_Engine/b9a335a2-f653-44a1-8961-89051f2e958f.htm的位置。

通過AddItem添加到工具欄中的Command控件使用非常方便,添加了它以後你就再不用操心進一步的處理它與地圖控件的交互了。Engine內部是怎麼做到這一點的呢,記得我們在第一種方法中實例化一個Command控件時調用的OnCreate方法嗎,當時我們傳遞給它一個MapControl來告訴它需要控制哪一個地圖控件。而通過axToolbarControl1.AddItem添加的控件,由於ToolbarControl將這個控件放到自己的控件池時,就已經調用了它的OnCreate方法,並傳遞給了它自己的BuddyControl作爲控制對象,於是,一切都變得簡單了。

在實際開發項目中,我們往往不想暴露出ArcEngine內置的ToolBar控件,而是給用戶展示我們自己開發的工具欄控件。另一方面,我們也想使用這種簡單的添加控件機制。如果做到呢,方法就是在設計階段,仍然拖放一個ToolbarControl到窗體上,但是在屬性中將它的Visible設置爲false,這樣就不會顯示出來了,而我們可以往這個工具欄中添加大量的Command控件。

這個隱藏的工具欄如何使用呢,請看下面這個函數:

public void SetCurrentMapTool(string commandName)
{
  
//先重置地圖當前工具
  m_Map.CurrentTool = null;
  
for (int i = 0; i < m_toolbarControl.CommandPool.Count; i++)
  {
    _command 
= m_toolbarControl.CommandPool.get_Command(i);

    
if (_command.Name == commandName)
    {
      m_Map.CurrentTool 
= _command as ITool;
      _command.OnClick();
      
break;
    }
  }
}


前面提到ToolbarControl內部維護一個Command池,在這個池中存放了所有已添加的Command對象,獲取其中的Command可以通過CommandPool的get_Command方法,通過比較Command的名稱,可以得到想要的Command對象。這個名稱可不同於ProgID,它是另一個用來標識Command控件的字符串,具體的請在Built-in commands上查找(第一列),比如我們之前添加的ZoomInTool控件,它的ProgID是esriControls.ControlsMapZoomInTool,它的Name是ControlToolsMapNavigation_ZoomIn。
請注意這一行:

m_Map.CurrentTool = _command as ITool;


當Command對象處理的不只是打開地圖,顯示全圖這類沒有與地圖交互的功能時,簡單的使用OnClick即可,但是當需要的是拖動鼠標控制縮放,空間查詢這類必須與地圖進行交互的動作時,就必須設置MapControl的CurrentTool屬性。

通過上面介紹的方法,就可以不僅利用Toolbar控件管理Command功能,又可以提供豐富的UI,保證表現層的靈活性。

內置的一系列Command控件可以滿足我們很多的功能需求,但是仍有稍顯不足的時候,比如Identify控件的全英文界面,會使有些用戶抓狂。這時,我們可以通過自己開發Command控件來擴展出我們需要的功能,並可以像內置Command一樣的使用。以後的文章會給大家來介紹。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章