利用arcgis engine、vs
.net和windows控件開發gis應用
dixon整理
此過程說明适合那些使用.net建立和部署應用的開發者,它描述了使用arcgis控件建立和部署應用的方法和步驟。
你可以在下面的目錄下找到相應的樣例程式:
<安裝目錄>/developerkit/samples/developer_guide_scenarios/
arcgis_engine/building_an_arcgis_control_application/map_viewer
注:arcgis樣例程式不包含在arcgis
engine開發工具包“典型”安裝方式中。如果你沒有安裝它們,則可以重新運作開發工具包安裝向導,選擇“定制”或“修改”方式,并選擇軟體開發包下的樣例項進行安裝。
一、項目描述
利用視窗控件建立應用程式的目标是示範并使你熟悉在微軟visual studio .net api中使用标準arcgis控件開發和部署gis應用所需的步聚。本節中使用了visual
studio .net開發環境中的mapcontrol、
本節示範了建立檢視arcmap和arcgis桌面應用圖形文檔的gis應用程式的步驟。此節包含了以下技術:
l在微軟visual studio .net中加載和嵌入arcgis控件。
l向pagelayoutcontrol和mapcontrol中加載圖形文檔。
l設定toolbarcontrol和toccontrol的綁定控件。
l處理視窗縮放。
l向toolbarcontrol添加arcgis
engine指令和工具。
l建立彈出式菜單
l在toccontrol中管理标簽編輯
l在mapcontrol中繪制圖形。
l為mapcontrol、pagelayoutcontrol和toolbarcontrol建立定制工具。
l使用者化toolbarcontrol。
l在windows作業系統中部署應用。
二、概述
本方案使用微軟visual studio .net開發環境加以實作,并使用了esri
interop程式集(interop assemblies),它服務于被放置在.net窗體上的、位于.net
窗體控件(.net windows controls)中的arcgis控件,這些程式集在托管的.net代碼和非托管的com代碼之間起了橋梁作用。對com
arcgis控件(com arcgis controls)成員的引用都要經過interop程式集,然後到達實際的com對象。同樣,也從com對象經過interop程式集到達.net應用程式。每個arcgis
engine控件具有方法、屬性與事件,它們能夠被控件嵌入的容器(如,.net窗體)通路。每個控件對象及其功能可以與其他esri
arcobjects和自定義控件組合使用,建立使用者化的客戶應用程式。
此方案是使用了c#和visual
basic .net兩種語言建立,但以下技術實作集中傾向于c#方案。許多開發者可能會感覺用visual
basic .net更舒服,那是因為他們已經比較熟悉visual basic 6.0代碼,然而,對于java和c++程式員來說,他們将會覺得對c#程式語言的文法更熟悉。無論你使用哪種開發環境,對于使用arcgis控件的好壞既依賴于你的程式設計環境技術,也依賴于你所掌握的arcobjects技術。
在本方案中,使用toolbarcontrol、toccontrol、pagelayoutcontrol和mapcontrol來為應用程式提供使用者界面。這些arcgis控件與其他arcobjects和arcgis
engine指令被開發者一起使用,用來建立一個gis視窗應用。
三、設計
此方案在設計時,首先強調了arcgis
控件如何互相之間進行互動,其次,向開發者解釋說明了arcgis
控件對象模型的一部分。
每個.net arcgis engine控件包含有一套能夠被嵌入其内的視窗即時通路的屬性頁。這些屬性些為控件屬性和方法的選擇提供了捷徑,并且允許開發者不寫任何代碼即可建立一個應用程式。本方案并沒有使用屬性頁,而是采用寫代碼的方式建立應用程式。關于屬性頁的更進一步的資訊,請參考arcgis開發幫助(arcgis
developer help)。
四、條件需求
要順利地完成以下方案,你需要以下條件(對于部署的需求将在後續的部署章節涉及到):
l安裝具有授權檔案的arcgis engine開發工具包(developer
kit),使之能夠用于開發。
l安裝有微軟visual studio .net 2003開發環境和微軟.net
framework 1.1及其相應協定。
l熟悉微軟windows作業系統和microsoft
visual studio .net的工作知識,會用c#或visual
basic .net程式設計語言。當然,此方案中提供了一些如何在microsoft visual studio .net中使用arcgis控件的資訊,但它不能替代對開發環境的教育訓練。
l不需要對esri其它軟體有足夠的經驗,但如果以前對arcobjects有所接觸并對arcgis應用(如,arccatalog,arcmap)有一個基本了解,則對于開發更有利。
l通路來自本方案的樣例資料和代碼,它位于:
本方案中使用到的控件和庫如下:
laxmapcontrol
laxtoccontrol
laxpagelayoutcontrol
laxtoolbarcontrol
lesri.arcgis.carto
lesri.arcgis.system
lesri.arcgis.display
lesri.arcgis.systemui
lesri.arcgis.geometry
lesri.arcgis.utility
lesrimapcontrol
lesritoccontrol
lesripagelayoutcontrol
lesritoolbarcontrol
下面的實作過程中提供了你成功完成方案所需所有代碼。假設你對于開發環境已經有了一定的知識,是以下面沒有逐漸地詳細介紹如何用microsoft visual studio .net開發應用。
在你為應用程式編寫代碼之前,應該先将應用程式将用到的arcgis控件和其他arcgis
engine庫引用裝載到開發環境之中。
1.啟動visual
studio .net,并從建立項目對話框中建立一個新的visual c#
“windows應用程式”項目。
2.将項目命名為“controls”,并選擇位置存取該項目。
3.在“工具箱”的“windows窗體”标簽欄中單擊右鍵,然後從上下文菜單中選擇“添加/移除項(i)…”。
4.在“自定義工具箱”中選擇“.net
framework元件”,并複選“axmapcontrol”,“axpagelayoutcontrol”,“axtoccontrol”和“axtoolbarcontrol”,單擊确定按鈕。這樣所選擇的控件将顯示在工具箱的windows窗體标簽欄中。
<a target="_blank" href="http://upfiles/2004102528278.jpg"></a>
5.單擊項目菜單,并選擇“添加引用(r)…”。
6.在添加引用對話框中,輕按兩下“esri.arcgis.carto”,“esri.arcgis.display”,“esri.arcgis.geometry”,“esri.arcgis.system”,“esri.arcgis.systemui”,“esri.arcgis.utility”。單擊确定。
注:對于esri .net程式集,将通過具體執行個體來說明,并使用.net架構提供的com傳送服務從你的c#項目中調用esri對象庫中的實體對象。
在你能夠通路每個控件的事件、屬性和方法之前,需要将控件嵌入到.net容器中。一旦将控件嵌入窗體内,它們将圖形化應用程式的使用者界面。
1.在設計模式下打開.net窗體。
2.輕按兩下工具箱windows标簽欄中的axmapcontrol控件,将mapcontrol加入到窗體上。
3.再将axpagelayoutcontrol、axtoccontrol和axtoolbarcontrol如上添加到窗體中。
4.重新調整窗體上各個控件的大小和位置,調整結果如下所示。
5.在窗體上輕按兩下顯示窗體代碼視窗,在代碼視窗的頂部增加“using”指令:
using system;
using system.windows.forms;
// arcgis engine引用
using esri.arcgis.systemui;
using esri.arcgis.carto;
using esri.arcgis.display;
using esri.arcgis.geometry;
using esri.arcgis.esrisystem;
using esri.arcgis.toolbarcontrol;
using esri.arcgis.toccontrol;
注:需注意c#是區分大小寫的。當你鍵入“esri.”時,智能敏感的自動完成功能将允許你通過按tab鍵完成下一節。
單獨的資料層或者使用arcmap、arcgis桌面應用程式産生的圖形文檔,能夠被加載到mapcontrol和pagelayoutcontrol中。你可以加載樣例圖形文檔,或者加載你自己的圖形文檔。後面你将增加一個浏覽圖形文檔的對話框。
1.選擇form_load事件,并輸入下列代碼(如果你使用你自己的圖形文檔,要替換為正确的檔案名):
// 使用相對路徑向pagelayoutcontrol加載一個圖形文檔
string filename = @"../../../../../../../../data//arcgis_engine_developer_guide//gulf of st. lawrence.mxd";
if ( axpagelayoutcontrol1.checkmxfile(filename) )
{
axpagelayoutcontrol1.loadmxfile(filename, "");
}
2.在設計模式顯示窗體并從屬性窗選擇axpagelayoutcontrol1控件,顯示axpagelayoutcontrol事件。在onpagelayoutreplaced事件上輕按兩下向代碼視窗添加該事件的處理函數。
3.在axpagelayoutcontrol1_onpagelayoutreplaced事件中鍵入以下向mapcontrol加載樣例圖形文檔的代碼。當文檔被裝載入pagelayoutcontrol時onpagelayoutreplaced事件将會被觸發。
privatevoid axpagelayoutcontrol1_onpagelayoutreplaced(object sender, esri.arcgis.pagelayoutcontrol.ipagelayoutcontrolevents_onpagelayoutreplacedevent
e)
// 加載同樣的文檔到mapcontrol
axmapcontrol1.loadmxfile(axpagelayoutcontrol1.documentfilename,
null, null);
// 設定mapcontrol顯示範圍至資料的全局範圍
axmapcontrol1.extent = axmapcontrol1.fullextent;
對于此應用程式,toccontrol和toolbarcontrol控件将與pagelayoutcontrol互相協作,而不是mapcontrol。為此pagelayoutcontrol必須設定為綁定控件。toccontrol使用綁定的activeview顯示圖形、圖層和符号。而位于toolbarcontrol上的任何指令、工具或菜單項會受綁定控件的顯示影響。
1.在form_load事件中的加載文檔代碼的後面鍵入以下紅色部分内容:
privatevoid form1_load(object sender, system.eventargs e)
// 設定綁定控件
axtoccontrol1.setbuddycontrol(axpagelayoutcontrol1);
axtoolbarcontrol1.setbuddycontrol(axpagelayoutcontrol1);
2.生成并運作應用程式。圖形文檔被加載到pagelayoutcontrol,并且toccontrol列出了圖形文檔中的資料圖層。使用toccontrol通過複選和取消複選框控制圖層的可見性。預設地,圖形文檔的焦點圖(focus
map)被裝入mapcontrol控件。在這種目前情況下,toolbarcontrol控件顯示是空的,因為沒有為它添加任何指令。試着縮放窗體,你會注意到控件不會改變尺寸。
當視窗在運作時進行縮放時,pagelayoutcontrol和mapcontrol不會自動改變自身的尺寸。要改變控件的尺寸以便它們總是與比對視窗的範圍,你必須将控件錨定在視窗上。如果pagelayoutcontrol或mapcontrol包含大量的資料,在視窗縮放期間重繪這些資料顯得相當重要。為了提高執行效率,你可以禁止資料重繪直到縮放操作完成後再重繪之。在縮放時,可以用一個可伸縮的位圖來替代重繪資料。
1.在設計模式顯示窗體并從屬性視窗中選擇axpagelayoutcontrol1。單擊anchor屬性,将axpagelayoutcontrol1錨定在窗體的頂、左、底和右部。
2.錨定axmapcontrol控件到窗體的頂、左和底部。
3.在form_load事件的開頭增加以下代碼:
// 當縮放時禁止重繪
this.setstyle(controlstyles.enablenotifymessage,
true);
4.向類增加以下常量:
publicclass form1 : system.windows.forms.form
// ……
privateconstint wm_entersizemove = 0x231;
privateconstint wm_exitsizemove = 0x232;
//
……
5.向重載的onnotifymessage方法中增加下列代碼:
protectedoverridevoid onnotifymessage(message m)
base.onnotifymessage (m);
// 以下為手工添加的代碼
if ( m.msg == wm_entersizemove)
axmapcontrol1.suppressresizedrawing(true, 0);
axpagelayoutcontrol1.suppressresizedrawing(true, 0);
elseif ( m.msg == wm_exitsizemove)
axmapcontrol1.suppressresizedrawing(false, 0);
axpagelayoutcontrol1.suppressresizedrawing(false, 0);
6.生成并運作應用程式,試着縮放視窗。
注:禁止縮放時重畫方法是通過檢查發送到窗體的windows消息工作的。當視窗開發縮放時,windows發送wm_entersizemove視窗消息。此時,我們禁止在mapcontrol和pagelayoutcontrol上繪制圖形,而是使用“stretchy bitmap”繪制。當windows發送wm_exitsizemove消息時,窗體結束縮放,這時我們全部重繪新的範圍。
arcgis engine提供了120多個指令和工具,它們與mapcontrol、pagelayoutcontrol和toolbarcontrol直接互相協作。這些指令和工具為你提供了大量的經常使用的地圖導航、圖形管理、地物選擇等方面的gis功能。現在将在你的應用程式中增加這些指令和工具的一部分。
1.在form_load事件中的加載文檔代碼之前添加如下代碼。
// 增加打開檔指令
string progid;
progid = "esricontroltoolsgeneric.controlsopendoccommand";
axtoolbarcontrol1.additem(progid, -1, -1,
false, 0,
esricommandstyles.esricommandstyleicononly);
// 增加pagelayout導航指令
progid = "esricontroltoolspagelayout.controlspagezoomintool";
true, 0,
progid = "esricontroltoolspagelayout.controlspagezoomouttool";
progid = "esricontroltoolspagelayout.controlspagepantool";
progid = "esricontroltoolspagelayout.controlspagezoomwholepagecommand";
progid = "esricontroltoolspagelayout.controlspagezoompagetolastextentbackcommand";
progid = "esricontroltoolspagelayout.controlspagezoompagetolastextentforwardcommand";
// 增加地圖導航指令
progid = "esricontroltoolsmapnavigation.controlsmapzoomintool";
progid = "esricontroltoolsmapnavigation.controlsmapzoomouttool";
progid = "esricontroltoolsmapnavigation.controlsmappantool";
progid = "esricontroltoolsmapnavigation.controlsmapfullextentcommand";
2.生成并運作應用程式。現在toolbarcontrol包含了arcgis
engine指令和工具,你可以使用它們導航加載到pagelayoutcontrol中的圖形文檔。使用頁面布局指令對目前的頁面布局進行導航控制,要對存在于資料架構中的資料進行導航則使用地圖指令。利用找開文檔指令可以浏覽并加載其他的圖形文檔。
與給跟綁定控件協作的toolbarcontrol增加arcgis
engine指令一樣,按照前面的步驟,你也可以從arcgis engine指令建立彈出式菜單。下面将向你的應用程式中增加與pagelayoutcontrol協作的彈出式菜單。當在pagelayoutcontrol可視區域點選滑鼠右鍵的時候,彈出式菜單将顯示。
1.向類中添加如下的成員變量(紅色部分):
private esri.arcgis.mapcontrol.axmapcontrol axmapcontrol1;
private esri.arcgis.pagelayoutcontrol.axpagelayoutcontrol axpagelayoutcontrol1;
private esri.arcgis.toccontrol.axtoccontrol axtoccontrol1;
private esri.arcgis.toolbarcontrol.axtoolbarcontrol axtoolbarcontrol1;
private itoolbarmenu m_toolbarmenu = new toolbarmenuclass(); //
彈出式菜單
2.在form_load事件中向toolbarcontrol增加指令代碼的後面加載文檔代碼的前面增加如下代碼。
// 前面是增加地圖導航的代碼……
// 共享toolbarcontrol的指令池
m_toolbarmenu.commandpool = axtoolbarcontrol1.commandpool;
// 向toolbarmenu增加指令
progid = "esricontroltoolspagelayout.controlspagezoominfixedcommand";
m_toolbarmenu.additem(progid, -1, -1,
false,
esricommandstyles.esricommandstyleiconandtext);
progid = "esricontroltoolspagelayout.controlspagezoomoutfixedcommand";
true,
// 設定與pagelayoutcontrol挂接
m_toolbarmenu.sethook(axpagelayoutcontrol1);
後面是加載圖形文檔的代碼……
3.在設計模式顯示窗體并從屬性視窗中選擇axpagelayoutcontrol1,顯示axpagelayoutcontrol事件。輕按兩下onmousedown事件,向代碼視窗中增加事件處理代碼。
4.在axpagelayoutcontrol1_onmousedown事件中增加如下代碼:
privatevoid axpagelayoutcontrol1_onmousedown(object sender, esri.arcgis.pagelayoutcontrol.ipagelayoutcontrolevents_onmousedownevent
// 彈出toolbarmenu
if ( e.button == 2)
m_toolbarmenu.popupmenu(e.x, e.y, axpagelayoutcontrol1.hwnd);
5.生成并運作應用程式。在pagelayoutcontrol的顯示區域單擊右鍵以顯示彈出菜單,并為頁面布局導航。
toccontrol預設允許使用者自動地切換圖層的可見性并改變顯示在目錄表中的名稱。你可以增加代碼防止使用者在編輯名稱時輸入空的字元串。
1.在form_load事件的開始增加下列代碼。
// 設定标簽編輯為手動方式
axtoccontrol1.labeledit = esritoccontroledit.esritoccontrolmanual;
後面是加載文檔代碼
2.在設計模式顯示窗體并從屬性視窗選擇axtoccontrol1控件,顯示axtoccontrol事件。輕按兩下onendlabeledit向代碼視窗添加事件處理函數。
3.在axtoccontrol1_onendlabeledit事件中添加以下代碼:
privatevoid axtoccontrol1_onendlabeledit(object sender, esri.arcgis.toccontrol.itoccontrolevents_onendlabeleditevent
// 禁止在編輯标簽時鍵入空字串
string newlabel = e.newlabel;
if ( newlabel.trim() == "" )
e.canedit = false;
4.生成并生成應用程式。編輯toccontrol控件的地圖、圖層、标題或圖例類的标簽,在其上點選一次,然後再點一次調用标簽編輯。試着用空字串替代标簽。在編輯期間,你可以随時使用鍵盤上的esc鍵取消編輯。
你可以将mapcontrol作為縮略圖窗體使用,并在其上繪制顯示pagelayoutcontrol内的焦點地圖的目前範圍。當你浏覽pagelayoutcontrol資料架構内的資料時,你将看到縮略圖視窗也進行了更新。
注:使用地圖導航工具導航焦點圖(活動圖)将改變pagelayoutcontrol中焦點地圖的範圍并引起mapcontrol更新。使用頁面布局工具導航頁面布局将改變頁面布局的範圍(不是pagelayoutcontrol中的焦點圖的範圍),而mapcontrol将不更新。
1.向類中增加下列成員變量:
private itoolbarmenu m_toolbarmenu =
new toolbarmenuclass();
// 彈出式菜單
private ienvelope m_envelope;
// mapcontrol繪制的範圍
private object m_fillsymbol;
// 在mapcontrol上繪制範圍使用的符号
private itransformevents_visibleboundsupdatedeventhandler
visboundsupdatede;
// pagelayoutcontrol的焦點圖事件
注:聲明的變量visboundsupdatede是一個托管。托管是一個類,它能夠擁有對指定方法的引用,并使它連結到一個特定的事件。在事件和方法之間的連結過程有時在.net中被稱作wiring。
2.建立一個叫createoverviewsymbol的新函數。這個函數是建立你将在mapcontrol中使用的符号的地方,此符号是用來描述pagelayoutcontrol焦點地圖資料範圍的。函數中增加的代碼如下:
privatevoid createoverviewsymbol()
// 擷取irgbcolor接口
irgbcolor color = new rgbcolor();
// 設定顔色屬性
color.rgb = 255;
// 擷取iline符号接口
ilinesymbol outline = new simplelinesymbol();
// 設定線符号屬性
outline.width = 1.5;
outline.color = color;
// 擷取ifillsymbol接口
isimplefillsymbol simplefillsymbol =
new simplefillsymbolclass();
// 設定填充符号屬性
simplefillsymbol.outline = outline;
simplefillsymbol.style = esrisimplefillstyle.esrisfshollow;
m_fillsymbol = simplefillsymbol;
3.從form_load事件在toccontrol标簽編輯代碼之前調用createoverviewsymbol函數。
// 建立mapcontrol使用的符号
createoverviewsymbol();
// 下面是标簽編輯處理代碼
4.增加下列onvisibleboundsupdated函數。此函數将與地圖範圍改變時觸發的事件相連接配接,并用來設定新的地圖可見邊界範圍框。通過重新整理mapcontrol,你強制它重繪其上顯示的圖形。
privatevoid onvisibleboundsupdated(idisplaytransformation sender,
bool sizechanged)
// 設定新的可見範圍
m_envelope = sender.visiblebounds;
// 改變mapcontrol的前景狀态
axmapcontrol1.activeview.partialrefresh(
esriviewdrawphase,esriviewforeground,
null,
null);
5.pagelayoutcontrol預設的事件接口是ipagelayoutcontrolevents。這些事件不告訴我們資料邊框内的地圖範圍。為此你需要使用pagelayoutcontrol的焦點地圖的itransformevents接口。在pagelayoutcontrol_onpagelayoutreplaced事件進行中的加載文檔代碼前面增加以下代碼。
// 擷取pagelayoutcontrol中焦點地圖的iactiveview對象
iactiveview activeview = (iactiveview)
axpagelayoutcontrol1.activeview.focusmap;
// 捕捉pagelayoutcontrol的焦點圖的itransformevents事件
visboundsupdatede =
new itransformevents_visibleboundsupdatedeventhandler(onvisibleboundsupdated);
((itransformevents_event)activeview.screendisplay
.displaytransformation).visibleboundsupdated += visboundsupdatede;
// 擷取焦點圖的範圍
m_envelope = activeview.extent;
// 後面是加載地圖文檔的代碼
6.在設計模式下顯示窗體并從屬性窗中選擇axmapcontrol1,顯示axmapcontrol事件。輕按兩下onafterdraw向代碼視窗中增加事件處理。
7.向axmapcontrol1_onafterdraw事件進行中增加以下代碼,使用前面建立的符号繪制mapcontrol顯示邊框。
privatevoid axmapcontrol1_onafterdraw(object sender, esri.arcgis.mapcontrol.imapcontrolevents2_onafterdrawevent
if ( m_envelope ==
null)
return;
// 如果前景狀态被重繪
esriviewdrawphase viewdrawphase = (esriviewdrawphase)e.viewdrawphase;
if ( viewdrawphase == esriviewdrawphase.esriviewforeground )
igeometry geometry = m_envelope;
axmapcontrol1.drawshape(geometry,
ref m_fillsymbol);
生成并運作應用程式。使用你先前已經加好的地圖導航工具改變pagelayoutcontrol中焦點地圖的範圍。新的範圍被繪制在mapcontrol上。
建立協同mapcontrol和pagelayoutcontrol一起運作的自定義指令和工具,與你或許已經做過的建立esri
arcmap應用程式指令非常相似。你将建立一個在pagelayoutcontrol滑鼠點選位置添加包含當天日期的文本元素的自定義工具。不管用何種方法,建立同mapcontrol和toolbarcontrol協作的指令與同pagelayoutcontrol一樣。
這個自定義工具的相關代碼與其他本方案源代碼一樣很有用。如果你想要直接使用自定義指令,而不自己建立它,請直接到第24步。
1.從建立項目對話框建立一個新的visual
c# “類庫”項目。
2.将項目命名為“commands”,并選擇儲存位置存貯之。
3.單擊項目菜單并選擇“添加引用(r)…”。
4.在添加引用對話框中,複選“esri.arcgis.carto”,“esri.arcgis.display”,“esri.arcgis.geometry”,“esri.arcgis.system”,“esri.arcgis.systemui”,“esri.arcgis..utility”和“esri.arcgis.controlcommands”。
5.在項目中增加一個類,名字叫adddatetool。
6.點選項目菜單并選擇添加現有項,浏覽樣例源碼目錄并找到date.bmp檔案将其加入到你的項目。
7.在解決方案資料總管中點選date.bmp在屬性視窗顯示其屬性。改變生成操作屬性為嵌入的資源。這張位圖将被用來作為指令按鈕的外觀。
8.改變adddatetool的命名空間的名稱為csharpdotnetcommands。
namespace csharpdotnetcommands
注:要在visual basi .net中改變命名空間的名稱,則在解決方案資料總管的項目上點選右鍵并選擇屬性,在項目屬性頁中選擇正常并改變根命名空間後,按确定。
9.在adddatetool類代碼視窗的頂部增加以下引用。
using esri.arcgis.controlcommands;
using esri.arcgis.utility.baseclasses;
using system.runtime.interopservices;
10.指定adddatetool類繼承自esri
basetool抽象類,并增加密封(sealed)類修飾。
publicsealedclass adddatetool : basetool
注:抽象類是不能被執行個體化的類,通常僅包含部分實作代碼,或者不包含任何實作代碼。它們與接口密切相關;但與接口有明顯的差別,也就是說,一個類可能實作任意數量的接口,但它僅能夠從一個抽象類中繼承。繼承了esri basetool抽象類,你便可以比直接實作esrisystemui
icommand和itool接口更快速、簡便地建立指令和工具。
密封類修飾說明一個類不能被繼承。此類的設計是為了限制其他類從該類繼承。
11.向adddatetool類的構造函數中增加下列代碼:
public adddatetool()
// 擷取程式集中的資源數組
string[] res = gettype().assembly.getmanifestresourcenames();
// 設定工具屬性
base.m_bitmap =
new system.drawing.bitmap(
gettype().assembly.getmanifestresourcestream(res[0]));
base.m_caption = "添加日期";
base.m_category = "customcommands";
base.m_message = "在頁面布局中增加一個日期元素";
base.m_name = "customcommands_add date";
base.m_tooltip = "添加日期";
注:類構造函數是一個當類建立時被調用的方法。它可以用來初始化類成員變量。構造函數名與類名相同;與其他方法不同的是它沒有傳回類型。
程式中隻個别地替換實作了位圖、标題、目錄、名稱、消息和提示方法,你可以設定從這此方法傳回的值,且依賴于basetool類為這此方法提供的實作。其它的成員保留basetool類傳回的預設值。
12.向adddatetool類增加下列成員變量。
// hookhelper對象處理通過oncreate事件的回調
private ihookhelper m_hookhelper =
new hookhelperclass();
13.在類視圖視窗中,定位到basecommand類的oncreate方法,右鍵點選之顯示上下文菜單。選擇增加,然後重載并增加該方法至代碼視窗。
14.在重載的oncreate方法中增加以下代碼。
publicoverridevoid oncreate(object hook)
m_hookhelper.hook = hook;
注:要在visual basic .net中重載屬性和方法,從代碼視窗頂部的“class name”組合框中選擇“overrides”,從“method name”組合框中選擇屬性或方法。
15.在類視圖中定位到basecommand類的enabled屬性并在其上點選右鍵顯示上下文菜單。選擇添加,然後點重寫增加該屬性至代碼視窗。
16.增加以下代碼,重寫basetool類的預設enabled值。
publicoverridebool enabled
get
// 設定使能屬性
if ( m_hookhelper.activeview !=
null )
returntrue;
else
returnfalse;
注:icommand_oncreate事件向指令工作的應用程式傳送一個句柄或回調。在這種情況下,它可以是mapcontrol,pagelayoutcontrol或toolbarcontrol。除向oncreate事件增加代碼外,你可以使用hookhelper判斷傳向指令的回調類型。指令或工具需要知道如何處理傳送的回調,是以必須對arcgis control傳送的類型作檢查。hookhelper用來控件回調并傳回activeview忽略的回調類型(mapcontrol、pagelayoutcontrol和toolbarcontrol都是這樣)。
17.在類視圖中定位到basetool基類的onmousedown方法,并在其上點選右鍵顯示上下文菜單。選擇添加,然後重載并增加該屬性至代碼視窗。
18.增加下列代碼,重載basetool類實作的預設onmousedown函數。
publicoverridevoid onmousedown(int button,
int shift,
int x,
int y)
// todo: 添加 adddatetool.onmousedown
實作
base.onmousedown (button, shift, x, y);
// 擷取活動視圖
iactiveview activeview = m_hookhelper.activeview;
// 建立新的文本元素
itextelement textelement = new textelementclass();
// 建立文本符号
itextsymbol textsymbol = new textsymbolclass();
textsymbol.size = 25;
// 設定文本元素屬性
textelement.symbol = textsymbol;
textelement.text = datetime.now.toshortdatestring();
// 對ielementqi
ielement element = (ielement) textelement;
// 建立頁點
ipoint point = new pointclass();
point = activeview.screendisplay.displaytransformation.tomappoint(x, y);
// 設定元素圖形
element.geometry = point;
// 增加元素到圖形繪制容器
activeview.graphicscontainer.addelement(element, 0);
// 重新整理圖形
activeview.partialrefresh(esriviewdrawphase.esriviewgraphics,
19.arcgis engine期望自定義指令是一個com類;是以,你必須指定你所建立的.net類也成為一個com類,它是通過建立一個com可調用包裝(callable
wrapper)實作的。在解決方案資料總管視窗中,在commands項目上右擊滑鼠鍵并從上下文菜單中選擇屬性。
20.在項目屬性頁對話框中選擇配置屬性;并點選生成。在右面的面闆中,改變為“為com
interop注冊”為true,點确定。
注:設定“為com interop注冊”屬性為true會調用程式集注冊工具(regasm.exe)。這将增加用戶端期望找到的類資訊。
如果“為com interop注冊”屬性設為false,則使項目不要是一個c#類庫類型。
21.在adddatetool類的代碼編寫視窗的adddatetool類聲明的開始位置增加下列代碼,指定com需要的屬性。
[classinterface(classinterfacetype.none)]
[guid("d880184e-ac81-47e5-b363-781f4dc4528f")]
注:新的guid可能通過visual
studio .net中的guidgen.exe實用工具生成,或者從工具菜單中選擇建立guid。guid應該像上面的格式并不包含大括号(curly
braces)。
22.向adddatetool類成員變量的後面增加下列代碼。此代碼定義了一些函數,這些函數使用目錄實用工具向esri控件指令(esri
control commands)元件目錄注冊和取消注冊adddatetool類。
// 在“esri controls commands”元件目錄注冊
#region component category registration
[comregisterfunction()]
[comvisible(false)]
staticvoid registerfunction(string skey)
string fullkey = skey.remove(0, 18) + @"/nimplemented categories";
microsoft.win32.registrykey regkey =
microsoft.win32.registry.classesroot.opensubkey(fullkey,
if (regkey !=
regkey.createsubkey("{b284d891-22ee-4f12-a0a9-b1dded9197f4}");
[comunregisterfunction()]
staticvoid unregisterfunction(string skey)
string fullkey = skey.remove(0, 18) + @"/implemented categories";
regkey.deletesubkey("{b284d891-22ee-4f12-a0a9-b1dded9197f4}");
#endregion
23.生成工程。
24.在方案開始建立的visual
studio .net “windows應用程式”項目中,增加地圖導航指令代碼的後面增加以下代碼。
// 前面是指令導航代碼……
// 添加自定義日期工具
progid = "csharpdotnetcommands.adddatetool";
// 後面是toolbarmenu相關代碼……
25.生成并運作應用程式,使用添加日期工具向pagelayoutcontrol上增加一個包含當天日期的文本元素。
同在form_load事件中向toolbarcontrol控件增加arcgis
engine指令和工具一樣,你也可以使用定制對話框和自定義toolbarcontrol的方式添加指令和工具。要實作它,就要将toolbarcontrol置為定制模式并顯示定制對話框。
visboundsupdatede; // pagelayoutcontrol的焦點圖事件
private icustomizedialog m_customizedialog =
new
customizedialogclass(); // curtomizedialog被toolbarcontrol使用
private icustomizedialogevents_onstartdialogeventhandler
startdialoge; // customizedialog啟動事件
private icustomizedialogevents_onclosedialogeventhandler
closedialoge; // customizedialog關閉事件
注:visual studio .net提供了當程式集對com
interop開放時執行的函數在系統中被注冊和取消注冊的功能。這就允許你在定制對話框可能找到的元件目錄中注冊你自己的類。
2.建立一個叫createcustomizedialog的新函數,這個函數是你通過增加如下代碼建立自定義對話框的地方。
privatevoid createcustomizedialog()
// 設定自定義對話框事件
startdialoge =
icustomizedialogevents_onstartdialogeventhandler(onstartdialog);
((icustomizedialogevents_event)m_customizedialog).onstartdialog +=
startdialoge;
closedialoge =
icustomizedialogevents_onclosedialogeventhandler(onclosedialog);
((icustomizedialogevents_event)m_customizedialog).onclosedialog +=
closedialoge;
// 設定标題
m_customizedialog.dialogtitle = "自定義toolbarcontrol項目";
// 顯示“從檔案添加”按鈕
m_customizedialog.showaddfromfile = true;
// 設定将增加新項目的toolbarcontrol
m_customizedialog.setdoubleclickdestination(axtoolbarcontrol1);
注:設定comvisible屬性為false確定此方法不能被com用戶端直接調用。當程式集通過com注冊時,它不影響被調用的方法。
3.在form_load事件中調用createoverviewsymbol子過程以前調用createcustomizedialog函數。
// 為toolbarcontrol建立自定義對話框
createcustomizedialog();
4.在窗體上增加一個名叫“chkcustomize”的複選框,并将标題命名為“定制”。
5.在設計模式顯示窗體并從屬性視窗選擇chkcustomize控件,顯示chkcustomize事件。在checkedchanged事件上輕按兩下向代碼視窗增加相應的事件處理。
6.向chkcustomize_checkedchanged事件中增加下列代碼。
privatevoid chkcustomize_checkedchanged(object sender, system.eventargs e)
// 顯示或隐藏自定義對話框
if (chkcustomize.checked ==
false )
m_customizedialog.closedialog();
axtoolbarcontrol1.customize = false;
m_customizedialog.startdialog(axtoolbarcontrol1.hwnd);
axtoolbarcontrol1.customize = true;
7.增加下以下onstartdialog和onclosedialog事件處理函數。這些函數将與自定義對話框打開或關閉時觸發的事件緊密連接配接。
privatevoid onstartdialog()
privatevoid onclosedialog()
chkcustomize.checked = false;
8.生成并運作應用程式,選擇定制複選框使toolbarcontrol進入自定義模式,并打開自定義對話框。
9.在自定義toolbarcontrol項目對話框中的左邊目錄(categories)清單中選擇“graphic
element”項,然後在右邊的指令(commands)清單中“select
elements”項上輕按兩下将其加入到toolbarcontrol工具欄中。右鍵點選toolbarcontrol上的任何一個項目,你可以調整它的顯示樣式群組合特性。
10.結束定制應用。使用選擇工具移動包含日期的文本元素。
要将應用程式成功地部署到另一台機器上,必須為應用程式配置協定。首先,它必須檢查産品協定是否有效,其次,它必須初始化協定。如果協定配置不正确有,應用程式将不能運作。
注:當采用esri arcobjects開發獨立運作的程式時,應用程式負責檢查并配置協定選項。它通過實作coclass
aoinitialize和iaoinitialize接口來支援協定配置。應用程式運作時,在任何esri
arcobject功能被通路之前協定初始化必須先被執行。如果初始化失敗将導緻應用程式錯誤。
1.向類中增加下列成員變量。
// 應用初始化對象
private iaoinitialize m_aoinitialize =
new aoinitializeclass();
後面是彈出菜單變量聲明代碼
2.在form_load事件的最開始位置增加下列代碼。
// 建立新的aoinitialize對象
if ( m_aoinitialize ==
system.windows.forms.messagebox.show(
"初始化失敗,程式不能運作!");
this.close();
// 判斷産品是否有效
esrilicensestatus licensestatus = (esrilicensestatus)
m_aoinitialize.isproductcodeavailable(
esrilicenseproductcode.esrilicenseproductcodeengine);
if (licensestatus == esrilicensestatus.esrilicenseavailable )
licensestatus = (esrilicensestatus)
m_aoinitialize.initialize(esrilicenseproductcode.esrilicenseproductcodeengine);
if (licensestatus != esrilicensestatus.esrilicensecheckedout )
"初始化失敗,應用程式不能運作!");
"arcgis engine産品無效,此程式不能運作!");
後面是建立自定義對話框的代碼……
3.在設計模式顯示窗體并在屬性視窗選擇form1,顯示窗體事件。在closing事件上輕按兩下向代碼視窗增加事件處理代碼。
4.在form_closing事件中增加以下代碼:
privatevoid form1_closing(object sender, system.componentmodel.canceleventargs e)
// 釋放com對象并關閉aoinitialize對象
esri.arcgis.utility.comsupport.aouninitialize.shutdown();
m_aoinitialize.shutdown();
5.在release模式下生成項目和解決方案。
要将應用程式成功地部署到使用者機器上:
l要将應用程式的可執行檔案和包含自定義指令的動态連結庫dll釋出到使用者機器上。程式集注冊工具(regasm.exe)必須被用來向系統資料庫增加關于自定義類的資訊。
l使用者機器上需要安裝有arcgis engine運作時庫和标準arcgis
engine協定。
l客戶機上需要安裝microsoft .net framework
1.1。
下列資源可以幫助你了解和應用在本方案中在在的概念和技術。
l在arcgis engine開發工具包中包含了其他可用的文檔:arcgis開發幫助,元件幫助,對象模型圖表和适合于初學者的樣例程式。
l微軟visual studio .net開發環境中的文檔。
轉自:http://blog.csdn.net/yanleigis/article/details/2233674