在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等這樣的關鍵字,查看搜到的結果,根據名稱判斷是不是對話框,然後寫代碼測試下,就知道效果以及如何使用了。