首页 > 代码库 > ArcEngine - 地图和布局同步

ArcEngine - 地图和布局同步

  1,定义同步的类:

  1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Text;  5   6 namespace Engine.App_Code {  7     public class ControlsSynchronizer {  8         #region private field.  9         private ESRI.ArcGIS.Controls.IMapControl3 mapCtrl = null; 10         private ESRI.ArcGIS.Controls.IPageLayoutControl2 pageLayoutCtrl = null; 11  12         private ESRI.ArcGIS.SystemUI.ITool pageLayoutActiveTool = null; 13         private ESRI.ArcGIS.SystemUI.ITool mapActiveTool = null; 14  15         private bool isMapCtrlActive = true;    //默认情况MapControl为活动状态. 16  17         private System.Collections.ArrayList FrameworkControls = null;  //存储Toolbar,Toc等. 18         #endregion 19  20         #region Property. 21         public ESRI.ArcGIS.Controls.IMapControl3 MapControl { 22             get { 23                 return mapCtrl; 24             } 25  26             set { 27                 mapCtrl = value; 28             } 29         } 30  31         public ESRI.ArcGIS.Controls.IPageLayoutControl2 PageLayoutControl { 32             get { 33                 return pageLayoutCtrl; 34             } 35  36             set { 37                 pageLayoutCtrl = value; 38             } 39         } 40  41         public string ActiveViewType { 42             get { 43                 if (isMapCtrlActive) 44                     return "MapControl"; 45                 else 46                     return "PageLayoutControl"; 47             } 48         } 49  50         public object ActiveControl { 51             get { 52                 if (mapCtrl == null || pageLayoutCtrl == null) 53                     throw new ArgumentNullException("ControlsSynchronizer::ActiveControl:\r\nEither MapControl or PageLayoutControl are not initialized!"); 54                 if (isMapCtrlActive) 55                     return mapCtrl.Object; 56                 else 57                     return pageLayoutCtrl.Object; 58             } 59         } 60         #endregion 61  62         #region constructor 63         public ControlsSynchronizer(ESRI.ArcGIS.Controls.IMapControl3 mapCtrl, ESRI.ArcGIS.Controls.IPageLayoutControl2 pageLayoutCtrl) 64             : this() { 65             this.mapCtrl = mapCtrl; 66             this.pageLayoutCtrl = pageLayoutCtrl; 67         } 68  69         public ControlsSynchronizer() { 70             FrameworkControls = new System.Collections.ArrayList(); 71         } 72         #endregion 73  74         #region method. 75         public void ActivateMap() { 76             try { 77                 if (mapCtrl == null || pageLayoutCtrl == null) 78                     throw new ArgumentNullException("ControlsSynchronizer::ActivateMap:\r\nEither MapControl or PageLayoutControl are not initialized!"); 79                 //cache the current tool of the PageLayoutControl. 80                 if (pageLayoutCtrl.CurrentTool != null) 81                     pageLayoutActiveTool = pageLayoutCtrl.CurrentTool; 82                 //Deactivate PageLayoutControl. 83                 pageLayoutCtrl.ActiveView.Deactivate(); 84  85                 //Activate MapControl. 86                 mapCtrl.ActiveView.Activate(mapCtrl.hWnd); 87                 if (mapActiveTool != null) 88                     mapCtrl.CurrentTool = mapActiveTool; 89  90                 isMapCtrlActive = true; 91                 //Set buddy control. 92                 SetBuddies(mapCtrl.Object); 93             } 94             catch (System.Exception ex) { 95                 throw new ArgumentException("ControlsSynchronizer::ActivateMap:" + ex.Message); 96             } 97         } 98  99         public void ActivePageLayout() {100             try {101                 if (mapCtrl == null || pageLayoutCtrl == null)102                     throw new ArgumentNullException("ControlsSynchronizer::ActivateMap:\r\nEither MapControl or PageLayoutControl are not initialized!");103                 //cache the current tool of the MapControl.104                 if (mapCtrl.CurrentTool != null)105                     pageLayoutActiveTool = mapCtrl.CurrentTool;106 107                 mapCtrl.ActiveView.Deactivate();108 109                 pageLayoutCtrl.ActiveView.Activate(pageLayoutCtrl.hWnd);110 111                 //assign the last active tool that has been used on the PageLayoutControl back as the active tool.112                 if (pageLayoutActiveTool != null)113                     pageLayoutCtrl.CurrentTool = pageLayoutActiveTool;114 115                 isMapCtrlActive = false;116                 SetBuddies(pageLayoutCtrl.Object);117             }118             catch (System.Exception ex) {119                 throw new ArgumentException("ControlsSynchronizer::ActivePageLayout:" + ex.Message);120             }121         }122 123         public void ReplaceMap(ESRI.ArcGIS.Carto.IMap map) {124             if (map == null)125                 throw new ArgumentNullException("ControlsSynchronizer::ReplaceMap:\r\nNew map for replacement is not initialized!");126             if (mapCtrl == null || pageLayoutCtrl == null)127                 throw new ArgumentNullException("ControlsSynchronizer::ReplaceMap:\r\nEither MapControl or PageLayoutControl are not initialized!");128             ESRI.ArcGIS.Carto.IMaps maps = new Maps();129             maps.Add(map);130 131             //在激活PageLayout而替换PageLayout地图前,先记录当前活动的控件(是MapControl还是PageLayoutControl).132             bool m_isMapCtrlActive = isMapCtrlActive;133 134             //call replace map on the PageLayout in order to replace the focus map135             //we must call ActivatePageLayout, since it is the control we call ‘ReplaceMaps‘136             ActivePageLayout();137             pageLayoutCtrl.PageLayout.ReplaceMaps(maps);138 139             //assign the new map to the MapControl.140             mapCtrl.Map = map;141 142             //reset the active tools.143             mapActiveTool = null;144             pageLayoutActiveTool = null;145 146             //make sure that the last active control is activated.147             if (m_isMapCtrlActive) {148                 ActivateMap();149                 mapCtrl.ActiveView.Refresh();150             }151             else {152                 ActivePageLayout();153                 pageLayoutCtrl.ActiveView.Refresh();154             }155         }156 157         /// <summary>158         /// 将Toc,Toolbar添加到该类中.159         /// </summary>160         /// <param name="control"></param>161         public void AddFrameworkControl(object control) {162             if (control == null)163                 throw new ArgumentNullException("ControlsSynchronizer::AddFrameworkControl:\r\nAdded control is not initialized!");164             FrameworkControls.Add(control);165         }166 167         /// <summary>168         /// 将Toc,Toolbar移出该类.169         /// </summary>170         /// <param name="control"></param>171         public void RemoveFrameworkControl(object control) {172             if (control == null)173                 throw new ArgumentNullException("ControlsSynchronizer::RemoveFrameworkControl:\r\nAdded control is not initialized!");174             FrameworkControls.Remove(control);175         }176 177         public void RemoveFrameworkControlAt(int index) {178             if (index < 0 || index >= FrameworkControls.Count)179                 throw new ArgumentOutOfRangeException("ControlsSynchronizer::RemoveFrameworkControlAt:index is out of range");180             FrameworkControls.RemoveAt(index);181         }182 183         public void BindControls(bool activeMapFirst) {184             if (mapCtrl == null || pageLayoutCtrl == null)185                 throw new ArgumentNullException("ControlsSynchronizer::BindControls:\r\nEither MapControl or PageLayoutControl are not initialized!");186             ESRI.ArcGIS.Carto.IMap map = new ESRI.ArcGIS.Carto.MapClass();187             map.Name = "Map";188 189             ESRI.ArcGIS.Carto.IMaps maps = new Maps();190             maps.Add(map);191 192             pageLayoutCtrl.PageLayout.ReplaceMaps(maps);193             mapCtrl.Map = map;194 195             mapActiveTool = null;196             pageLayoutActiveTool = null;197 198             if (activeMapFirst)199                 ActivateMap();200             else201                 ActivePageLayout();202         }203 204         public void BindControls(ESRI.ArcGIS.Controls.IMapControl3 mapCtrl, ESRI.ArcGIS.Controls.IPageLayoutControl2 pageLayoutCtrl, bool activeMapFirst) {205             this.mapCtrl = mapCtrl;206             this.pageLayoutCtrl = pageLayoutCtrl;207             BindControls(activeMapFirst);208         }209 210         /// <summary>211         /// 分别设置TOC,Toolbar的Buddy控件.212         /// </summary>213         /// <param name="buddy"></param>214         private void SetBuddies(object buddy) {215             try {216                 if (buddy == null)217                     throw new ArgumentNullException("ControlsSynchronizer::SetBuddies:\r\nTarget Buddy Control is not initialized!");218                 foreach (object ctrl in FrameworkControls) {219                     if (ctrl is ESRI.ArcGIS.Controls.IToolbarControl)220                         ((ESRI.ArcGIS.Controls.IToolbarControl)ctrl).SetBuddyControl(buddy);221                     else if (ctrl is ESRI.ArcGIS.Controls.ITOCControl)222                         ((ESRI.ArcGIS.Controls.ITOCControl)ctrl).SetBuddyControl(buddy);223                 }224             }225             catch (System.Exception ex) {226                 throw new ArgumentException("ControlsSynchronizer::SetBuddies:" + ex.Message);227             }228         }229         #endregion230     }231 }

  2,定义辅助类,用于存储地图:

  1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Text;  5   6 namespace Engine.App_Code {  7     /// <summary>  8     /// Implementation of interface IMaps which is eventually a collection of Maps.  9     /// </summary> 10     class Maps : ESRI.ArcGIS.Carto.IMaps, IDisposable { 11         #region private member. 12         //class member - using internally an ArrayList to manage the Maps collection. 13         private System.Collections.ArrayList arr_maps = null; 14         #endregion 15  16         #region class constructor. 17         public Maps() { 18             arr_maps = new System.Collections.ArrayList(); 19         } 20         #endregion 21  22         #region dispose member. 23         /// <summary> 24         /// Dispose the Maps collection. 25         /// </summary> 26         public void Dispose() { 27             if (arr_maps != null) { 28                 arr_maps.Clear(); 29                 arr_maps = null; 30             } 31         } 32         #endregion 33  34         #region IMap member. 35         /// <summary> 36         /// Add the given map the the Map collection. 37         /// </summary> 38         /// <param name="Map"></param> 39         public void Add(ESRI.ArcGIS.Carto.IMap Map) { 40             if (Map == null) 41                 throw new Exception("Maps::Add:\r\nNew Map is mot initialized!"); 42             arr_maps.Add(Map); 43         } 44  45         /// <summary> 46         /// Get the number of Maps in the collection. 47         /// </summary> 48         public int Count { 49             get { 50                 return arr_maps.Count; 51             } 52         } 53  54         /// <summary> 55         /// Create a new Map, add it to the collection and return it to the caller. 56         /// </summary> 57         /// <returns></returns> 58         public ESRI.ArcGIS.Carto.IMap Create() { 59             ESRI.ArcGIS.Carto.IMap mapNew = new ESRI.ArcGIS.Carto.MapClass(); 60             arr_maps.Add(mapNew); 61             return mapNew; 62         } 63  64         /// <summary> 65         /// Remove the instance of the given Map. 66         /// </summary> 67         /// <param name="Map"></param> 68         public void Remove(ESRI.ArcGIS.Carto.IMap Map) { 69             arr_maps.Remove(Map); 70         } 71  72         /// <summary> 73         /// Remove the Map at the given index. 74         /// </summary> 75         /// <param name="Index"></param> 76         public void RemoveAt(int Index) { 77             if (Index < 0 || Index >= arr_maps.Count) 78                 throw new ArgumentOutOfRangeException("Maps::get_Item:Index is out of range!"); 79             arr_maps.RemoveAt(Index); 80         } 81  82         /// <summary> 83         /// Reset the Maps array. 84         /// </summary> 85         public void Reset() { 86             arr_maps.Clear(); 87         } 88  89         /// <summary> 90         /// Return the Map at the given index. 91         /// </summary> 92         /// <param name="Index"></param> 93         /// <returns></returns> 94         public ESRI.ArcGIS.Carto.IMap get_Item(int Index) { 95             if (Index < 0 || Index >= arr_maps.Count) 96                 throw new ArgumentOutOfRangeException("Maps::get_Item:Index is out of range!"); 97             return (ESRI.ArcGIS.Carto.IMap)arr_maps[Index]; 98         } 99         #endregion100     }101 }

  3,添加实现BaseCommand的类,用于打开地图:

  1 using System;  2 using System.Drawing;  3 using System.Runtime.InteropServices;  4 using ESRI.ArcGIS.ADF.BaseClasses;  5 using ESRI.ArcGIS.ADF.CATIDs;  6 using ESRI.ArcGIS.Controls;  7   8 namespace Engine.App_Code {  9     /// <summary> 10     /// Summary description for OpenMxdCommand. 11     /// </summary> 12     [Guid("ce02d34f-135a-42f5-9955-80402160acf9")] 13     [ClassInterface(ClassInterfaceType.None)] 14     [ProgId("Engine.App_Code.OpenMxdCommand")] 15     public sealed class OpenMxdCommand : BaseCommand { 16         public string DocumentFileName { 17             get; 18             private set; 19         } 20  21         #region COM Registration Function(s) 22         [ComRegisterFunction()] 23         [ComVisible(false)] 24         static void RegisterFunction(Type registerType) { 25             // Required for ArcGIS Component Category Registrar support 26             ArcGISCategoryRegistration(registerType); 27  28             // 29             // TODO: Add any COM registration code here 30             // 31         } 32  33         [ComUnregisterFunction()] 34         [ComVisible(false)] 35         static void UnregisterFunction(Type registerType) { 36             // Required for ArcGIS Component Category Registrar support 37             ArcGISCategoryUnregistration(registerType); 38  39             // 40             // TODO: Add any COM unregistration code here 41             // 42         } 43  44         #region ArcGIS Component Category Registrar generated code 45         /// <summary> 46         /// Required method for ArcGIS Component Category registration - 47         /// Do not modify the contents of this method with the code editor. 48         /// </summary> 49         private static void ArcGISCategoryRegistration(Type registerType) { 50             string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID); 51             ControlsCommands.Register(regKey); 52  53         } 54         /// <summary> 55         /// Required method for ArcGIS Component Category unregistration - 56         /// Do not modify the contents of this method with the code editor. 57         /// </summary> 58         private static void ArcGISCategoryUnregistration(Type registerType) { 59             string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID); 60             ControlsCommands.Unregister(regKey); 61  62         } 63  64         #endregion 65         #endregion 66  67         private IHookHelper m_hookHelper; 68         private IMapControl3 mapCtrl = null; 69  70         private ControlsSynchronizer controlsSynchronizer; 71  72  73  74         public OpenMxdCommand() { 75             base.m_category = "打开地图文档"; //localizable text 76             base.m_caption = "打开地图文档";  //localizable text 77             base.m_message = "打开地图文档";  //localizable text  78             base.m_toolTip = "打开地图文档";  //localizable text  79             base.m_name = "打开地图文档";   //unique id, non-localizable (e.g. "MyCategory_MyCommand") 80  81             try { 82                 string bitmapResourceName = GetType().Name + ".bmp"; 83                 base.m_bitmap = new Bitmap(GetType(), bitmapResourceName); 84             } 85             catch (Exception ex) { 86                 System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap"); 87             } 88         } 89  90         public OpenMxdCommand(ControlsSynchronizer controlsSynchronizer) 91             : this() { 92                 this.controlsSynchronizer = controlsSynchronizer; 93         } 94  95         #region Overridden Class Methods 96  97         /// <summary> 98         /// Occurs when this command is created 99         /// </summary>100         /// <param name="hook">Instance of the application</param>101         public override void OnCreate(object hook) {102             if (hook == null)103                 return;104 105             if (m_hookHelper == null)106                 m_hookHelper = new HookHelperClass();107 108 109             m_hookHelper.Hook = hook;110 111             if (hook is IToolbarControl) {112                 IToolbarControl tbarCtrl = (IToolbarControl)hook;113                 mapCtrl = (IMapControl3)tbarCtrl.Buddy;114             }115             else if (hook is IMapControl3)116                 mapCtrl = (IMapControl3)hook;117         }118 119         /// <summary>120         /// Occurs when this command is clicked121         /// </summary>122         public override void OnClick() {123             System.Windows.Forms.OpenFileDialog openMxdDlg = new System.Windows.Forms.OpenFileDialog();124             openMxdDlg.Filter = "Map Document(*.mxd)|*.mxd";125             openMxdDlg.Multiselect = false;126             openMxdDlg.Title = "Open map document";127             if (openMxdDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) {128                 string fileName = openMxdDlg.FileName;129                 ESRI.ArcGIS.Carto.IMapDocument mDoc = new ESRI.ArcGIS.Carto.MapDocumentClass();130                 //权限验证.131                 if (mDoc.get_IsPresent(fileName) && !mDoc.get_IsPasswordProtected(fileName)) {132                     //mapCtrl.LoadMxFile(fileName);133                     //mapCtrl.Extent = mapCtrl.FullExtent;    //全幅.134                     //mapCtrl.ActiveView.Refresh();135 136                     mDoc.Open(fileName);137                     ESRI.ArcGIS.Carto.IMap map = mDoc.get_Map(0);138                     mDoc.SetActiveView((ESRI.ArcGIS.Carto.IActiveView)map);139                     controlsSynchronizer.PageLayoutControl.PageLayout = mDoc.PageLayout;140                     controlsSynchronizer.ReplaceMap(map);141                     DocumentFileName = fileName;142                     mDoc.Close(); //?.143                 }144             }145         }146 147         #endregion148     }149 }

   4,在tabControl的 SelectedIndexChanged事件添加响应方法:

1 private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) {2             if (tabControl1.SelectedIndex == 0)3                 synchronizer.ActivateMap();4             else5                 synchronizer.ActivePageLayout();6         }

 

ArcEngine - 地图和布局同步