在ArcMap中,一些對話方塊是很複雜的,例如設定點線面樣式的對話方塊,選擇空間參考的對話方塊等,但這些對話方塊有些在ArcObjects SDK中是可以直接呼叫的。
var mySpatialReference = this.UI_SpatialReference_TextBox.Tag as ISpatialReference; if (mySpatialReference == null) { return; } var mySpatialReferenceDialog = new SpatialReferenceDialogClass { BasicMap = this._Grid.BasicMap }; mySpatialReference = mySpatialReferenceDialog.DoModalEdit(mySpatialReference, true, false, false, false, false, 0) as ISpatialReference; if (mySpatialReference != null) { this.UI_SpatialReference_TextBox.Text = mySpatialReference.Name; this.UI_SpatialReference_TextBox.Tag = mySpatialReference; }
我們看下SpatialReferenceDialogClass類的定義。
BasicMap屬性,該屬性是可以在彈出對話方塊中快速選擇當前地圖圖層的空間參考,不設定也可以。
DoModalEdit函式,該函式是主函式,即彈出選擇對話方塊。該函式的定義如下。
public ISpatialReference DoModalEdit ( ISpatialReference inputSpatialReference, bool hasXY, bool hasZ, bool hasM, bool coordPageReadOnly, bool domainPageReadOnly, int hParent);
第一個函式就是我們傳入的要編輯的空間參考物件,接下來三個引數是指是否內包含xy、z和m,我一般設定為true,false,false。後面的引數分別設定coord選項卡是否只讀,domain選項卡是否只讀以及父窗體的標識,一般設定為false,false,0。
除了DoModalEdit函式外,還有DoModalCreate函式,該函式是建立一個新的空間參考,引數和DoModalEdit函式類似。
樣式選擇器對話方塊用來設定點、線和麵符號。呼叫程式碼如下所示。
ISymbolSelector mySymbolSelector = new SymbolSelectorClass(); mySymbolSelector.AddSymbol(myLineSymbol as ISymbol); bool myIsOk = mySymbolSelector.SelectSymbol(0); if (myIsOk) { myLineSymbol = mySymbolSelector.GetSymbolAt(0) as ILineSymbol; }
主要用到的類是SymbolSelectorClass,透過AddSymbol函式,設定要編輯的樣式物件,呼叫SelectSymbol函式,彈出樣式選擇和設定對話方塊,並返回是否點選確定按鈕,如果點選了確定,可以透過GetSymbolAt函式獲取選擇或者編輯後的樣式物件。
點選右側的Edite Symbol按鈕,可以彈出更詳細的參設定對話方塊,如下圖所示。
IColor myColor = new RgbColor() { Red = 255, Blue = 0, Green = 0 }; IColorBrowser myColorBrowser = new ColorBrowser() { Color = myColor }; if (myColorBrowser.DoModal(0)) { myColor = myColorBrowser.Color; }
IColor myColor = new RgbColor() { Red = 255, Blue = 0, Green = 0 }; IColorSelector myColorSelector = new ColorSelectorClass() { Color = myColor }; if (myColorSelector.DoModal(0)) { myColor = myColorSelector.Color; }
但一般情況下我們都會呼叫.Net或者第三方UI自帶的顏色選擇器,基本不怎麼用ArcOObjects SDK的顏色設定對話方塊。
該對話方塊的主介面為IStyleSelector,我看下該介面的定義。
從幫助中可以看出,實現該介面的有背景選擇器,邊線選擇器,圖例元素、指北針、比例尺等。但實際測試的時候這些對話方塊並不彈出來,但看網上有人說是可以彈出來的,並貼出了圖片。難道是因為我的UI是用的WPF的原因?研究了半天沒搞明白,就放棄了,使用AxSymbologyControl,自己包裝了一個對話方塊。
5、使用AxSymbologyControl自定義樣式選擇設定對話方塊
AxSymbologyControl是一個基於winform的UI,我們可以把這個UI放對話方塊中,自定義一個樣式選擇設定對話方塊。使用AxSymbologyControl有兩個關鍵點,一是設定要顯示的符號型別,二是要設定載入的ServerStyle檔案。程式碼如下圖所示。
this._AxSymbologyControl = new AxSymbologyControl(); this._AxSymbologyControl.BeginInit(); this.UI_WindowsFormsHost.Child = this._AxSymbologyControl; this._AxSymbologyControl.EndInit(); this._AxSymbologyControl.StyleClass = pSymbologyStyle; string myInstall = ESRI.ArcGIS.RuntimeManager.ActiveRuntime.Path; string myEsriStyleFile = myInstall + "\\Styles\\ESRI.serverstyle"; if (File.Exists(myEsriStyleFile)) { this._AxSymbologyControl.LoadStyleFile(myEsriStyleFile); }
AxSymbologyControl.StyleClass屬性的型別為esriSymbologyStyleClass,該列舉的定義如下。
這說明AxSymbologyControl可以載入這麼多型別,因為使用IStyleSelector不能彈出選擇邊框的對話方塊,那麼我們就用在AxSymbologyControl上設定一下邊框,也就是esriSymbologyStyleClass。彈出的對話方塊如下圖所示。
這個對話方塊是我們自己定義的,裡面放了AxSymbologyControl,右上角是一個符號預覽UI。
這個介面直接翻譯是屬性頁面的意思,實際上可以TabControl裡面的一個選項卡,放到對話方塊中。透過檢視有哪些類繼承了該介面,我們可以瞭解到我們能直接用哪些UI。這些可以在幫助中檢視。
我們檢視幫助中,發現有一些和FeatureLayer有關的實現類,那麼我們是不是可以把這些PropertyPage組合在一起,形成一個對話方塊呢?程式碼如下。
ILayer mySelectLayer = this.MapApplication.SelectTocObject as ILayer; if (mySelectLayer == null) { return; } ESRI.ArcGIS.Framework.IComPropertySheet myComPropertySheet = new ESRI.ArcGIS.Framework.ComPropertySheet(); myComPropertySheet.Title = mySelectLayer.Name + " - Properties"; ESRI.ArcGIS.esriSystem.UID myUID = new ESRI.ArcGIS.esriSystem.UIDClass(); myComPropertySheet.AddCategoryID(myUID); myComPropertySheet.AddPage(new ESRI.ArcGIS.CartoUI.GeneralLayerPropPageClass()); if (mySelectLayer is IFeatureLayer) { myComPropertySheet.AddPage(new ESRI.ArcGIS.CartoUI.FeatureLayerSourcePropertyPageClass()); myComPropertySheet.AddPage(new ESRI.ArcGIS.CartoUI.LayerFieldsPropertyPageClass()); myComPropertySheet.AddPage(new ESRI.ArcGIS.CartoUI.LayerDrawingPropertyPageClass()); myComPropertySheet.AddPage(new ESRI.ArcGIS.CartoUI.LayerLabelsPropertyPageClass()); myComPropertySheet.AddPage(new ESRI.ArcGIS.CartoUI.LayerDefinitionQueryPropertyPageClass()); } ESRI.ArcGIS.esriSystem.ISet mySet = new ESRI.ArcGIS.esriSystem.SetClass(); mySet.Add(mySelectLayer); mySet.Reset(); myComPropertySheet.ActivePage = 2; bool myIsOK = myComPropertySheet.EditProperties(mySet, 0); if (myIsOK == false) { return; } this.MapApplication.TOCControl.Update(); this.MapApplication.ActiveView.Refresh();
ComPropertySheet為我們定義的一個主對話方塊,透過AddPage函式,新增實現IPropertyPage介面的類。例如我們首先新增了GeneralLayerPropPageClass,判斷如果是向量圖層,右增加了圖層資料來源、圖層欄位管理、圖層渲染、標註以及預設查詢等頁面,,並預設啟用第二個。彈出的對話方塊如下。
向量圖層的Page定義比較全,柵格資料的就比較少了,沒有比較複雜的柵格資料渲染設定。這個問題諮詢過Esri中國的技術支援,給的回覆是確實沒有定義。如果有能直接呼叫柵格圖層渲染設定的皮膚的朋友,可以留言或私信告訴下,非常感謝。
INumberDialog myNumberDialog = new NumberDialogClass(); bool myIsOK = myNumberDialog.DoModal("輸入數字", 1.00, 5, 0); if (myIsOK == true) { MessageBox.Show(myNumberDialog.Value.ToString()); }
IGetStringDialog myGetStringDialog = new GetStringDialogClass(); bool myIsOK = myGetStringDialog.DoModal("輸入字串", "字串:", "初始的字串", 0); if (myIsOK == true) { MessageBox.Show(myGetStringDialog.Value.ToString()); }
ICoordinateDialog myCoordinateDialog = new CoordinateDialogClass(); bool myIsOK = myCoordinateDialog.DoModal("輸入座標", 116, 42, 4, 0); if (myIsOK == true) { MessageBox.Show(myCoordinateDialog.X.ToString() + "," + myCoordinateDialog.Y.ToString()); }
不過這些對話方塊使用Winform或者WPF都比較容易實現,所以我們很少直接使用SDK裡面定義的這些。
ArcObjects SDK中可以直接呼叫的對話方塊還有很多,我們可以在幫助中搜尋例如Dialog、Window等這樣的關鍵字,檢視搜到的結果,根據名稱判斷是不是對話方塊,然後寫程式碼測試下,就知道效果以及如何使用了。