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 map

135             //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             else

201                 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         #endregion

230     }

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         #endregion

100     }

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 clicked

121         /// </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         #endregion

148     }

149 }

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

1 private void tabControl1_SelectedIndexChanged(object sender, EventArgs e) {

2             if (tabControl1.SelectedIndex == 0)

3                 synchronizer.ActivateMap();

4             else

5                 synchronizer.ActivePageLayout();

6         }

 

你可能感兴趣的:(ArcEngine)